Julia and dbscan clustering: how extract elements from resulting structure? - indexing

Warning: this is from a julia n00b!
After performing dbscan on a point coordinate array in Julia. (Note that this is not the 'distance based method' that returns 'assignments' as part of the result structure, but the 'adjacency list' method). Documentation here. I attempt to access the vector containing the indices, but I am at a loss when trying to retrieve the members of individual clusters:
dbr = dbscan(pointcoordinates, .1, min_neighbors = 10, min_cluster_size = 10)
13-element Array{DbscanCluster,1}:
DbscanCluster(17, [4, 12, 84, 90, 94, 675, 676, 737, 873, 965], [27, 108, 177, 880, 954, 1050, 1067])
DbscanCluster(10, Int64[], [46, 48, 51, 57, 188, 225, 226, 228, 270, 542])
DbscanCluster(11, [48, 51, 228], [46, 49, 57, 188, 225, 226, 270, 542])
DbscanCluster(14, [418, 759, 832, 988, 1046], [830, 831, 855, 865, 989, 991, 996, 1021, 1070])
DbscanCluster(10, Int64[], [624, 654, 664, 803, 805, 821, 859, 987, 1057, 1069])
It is easy to retrieve a single cluster from the array:
> dbr[1]
DbscanCluster(17, [4, 12, 84, 90, 94, 675, 676, 737, 873, 965], [27, 108, 177, 880, 954, 1050, 1067])
But how do i get the stuff inside DBscanCluster?
a = dbr[1]
DbscanCluster(17, [4, 12, 84, 90, 94, 675, 676, 737, 873, 965], [27, 108, 177, 880, 954, 1050, 1067])
In [258]:
a[1]
MethodError: no method matching getindex(::DbscanCluster, ::Int64)
Thank you for your help, and sorry if I am missing something glaring!

What makes you say that DbscanCluster is a child of array?
julia> DbscanCluster <: AbstractArray
false
You might be confused by Array{DbscanCluster,1} in your result, but this just tells you that the object returned by the dbscan call is an Array the elements of which are of type DbscanCluster - this does not tell you anything about whether those elements themselves are subtypes of Array.
As for how to get the indexes, the docs for DbscanResult show that the type has three fields:
seeds::Vector{Int}: indices of cluster starting points
assignments::Vector{Int}: vector of clusters indices, where each point was assigned to
counts::Vector{Int}: cluster sizes (number of assigned points)
each of which you can access with dot notation by doing e.g. drb[1].assignments.
If you want to get say the counts for all the 13 clusters in your results, you can broadcast getproperty like so:
getproperty.(drb, :counts)
Note that counts does not exist for in the case of the "adjacency lists" method of dbscan, one can use:
getproperty.(drb, :core_indices)

Related

How can I convert Bytes Array to String on Kotlin other than String()?

[51, -42, 119, -85, -64, 126, 22, 127, -72, 72, 48, -66, -18, 45, 99, -119]
This is the BytesArray that I want to print in String.
When I searched on the internet, I found that
String(Bytes, Charsets.UTF_8)
would convert it to String.
However, I get �؉���Q�t, and doesn't seem to be converted in right way.
Why is it?
I want it to be String in Alphabet characters and numbers
Firstly, you are specifying an array of signed bytes (indicated by negative numbers):
51, -42, 119, -85, -64, 126, 22, 127, -72, 72, 48, -66, -18, 45, 99, -119
Let's take a look at what this would hypothetically look like if it were unsigned (I used this tool for the conversion):
51, 214, 119, 171, 192, 126, 22, 127, 184, 72, 48, 190, 238, 45, 99, 137
Assuming by "Alphabet characters and numbers", you mean the English alphabet, then asciitable will help you identify each character's decimal value, but as a rough guide:
"0"-"9" = 48-57
"A"-"Z" = 65-90
"a"-"z" = 97-122
Consider the following code sample:
/**
* You can edit, run, and share this code.
* play.kotlinlang.org
*/
fun main() {
val bytes = byteArrayOf(51, -42, 119, -85, -64, 126, 22, 127, -72, 72, 48, -66, -18, 45, 99, -119)
val string = bytes.toString(Charsets.US_ASCII)
println(string)
}
As you can see, some of the values in the unsigned array fall outside of the range for English alphabetic characters and numbers, which is why you end up with a string, something like this "3�w��~�H0��-c�" depending on the charset you choose.
For reference:
Charset
Result
Charsets.US_ASCII
3�w��~�H0��-c�
Charsets.UTF_8
3�w��~�H0��-c�
Charsets.UTF_16
㏖瞫쁾ᙿ롈ゾ掉
Charsets.UTF_32
����
Charsets.ISO_8859_1
3Öw«À~¸H0¾î-c
So, it really depends on exactly which encoding the array is using, and exactly what it is you're expecting the resulting string to be.
You can play with the code above, here.

plotting many graph with matplolib (bargraph)

I have , dictionary
st={'Google Phone': [318, 379, 463, 580, 479, 391, 411, 359, 341, 597, 493, 714],
'iPhone': [381, 439, 537, 691, 640, 533, 501, 439, 396, 715, 664, 906],
'Vareebadd Phone': [125, 129,174,220,185,155,146,141,126,203,177,284]}
where all values in list are in following order:
Vareebadd Phone<Google phone<iphone
like---->381>318>125 || 439>379>129 for all values with same index
i got :
now if I put some change in
st={'Google Phone': [318, 379, 463, 580, 479, 391, 411, 359, 341, 597, 493, 714],
'iPhone': [381, 439, 537, 691, 640, 533, 501, 439, 396, 715, 664, 906],
'Vareebadd Phone': [125, 129,174,220,185,155,146,141,126,203,177,910]}
i got this:
my code is:
monthsname=['Jan','Feb','Mar','Apr','May','Jun','July','Aug','Sep','Oct','Nov','Dec']
plt.figure(figsize=(8,5))
plt.xticks(xpos,monthsname)
plt.bar(monthsname,st['iPhone'],w,label='iPhone')
plt.bar(monthsname,st['Google Phone'],w,label='Google Phone')
plt.bar(monthsname,st['Vareebadd Phone'],w,label='Vareebadd Phone')
# plt.figure(figsize=(10,5))
plt.legend()
plt.show()
If you are open to other packages, consider Pandas:
import pandas as pd
pd.DataFrame(st,index=monthsname ).plot.bar()
Output:
Or for the second data frame:
Is it what you are looking for?

PG:GroupingError only appearing on production

I have a model "Playlist" which has_many and belongs_to another model "User", through an intermediary model "PlaylistUser".
I have code that, for a given Playlist #playlist, lists all the other Playlists that share a User with #playlist, ordered by how many they share.
This code works perfectly on development, but on production, it's throwing this error:
PG::GroupingError: ERROR: column "playlists.name" must appear in the GROUP BY clause or be used in an aggregate function
LINE 1: SELECT "playlists".* FROM "playlists" INNER JOIN "playlist...
^
: SELECT "playlists".* FROM "playlists" INNER JOIN "playlist_users" ON "playlist_users"."playlist_id" = "playlists"."id" INNER JOIN "users" ON "users"."id" = "playlist_users"."user_id" WHERE (NOT (playlists.id = 30 OR playlists.id = 41)) AND "users"."id" IN (45, 89, 71, 117, 115, 173, 177, 180, 161, 220, 223, 199, 221, 239, 204, 205, 206, 207, 211, 261, 282, 284, 286, 251, 252, 255, 310, 311, 315, 318, 307, 362, 319, 306, 289, 316, 305, 321, 322, 330, 333, 292, 294, 304, 300, 340, 341, 342, 343, 405, 406, 410, 408, 409, 407, 413, 416, 417, 418, 425, 427, 392, 401, 403, 445, 446, 449, 450, 379, 456, 451, 454, 459, 437, 442, 444, 496, 501, 518, 548, 549, 533, 553, 1112, 1113, 1459, 455, 348, 1458, 242, 1275, 151, 1890, 336, 203, 404, 166, 453, 114, 157, 285, 448, 447, 443, 550, 2167, 2168, 287, 320, 293, 65, 2098, 2097, 2099, 387, 3, 2175, 2170, 2174, 2182, 2171, 438, 2180, 2181, 2169, 2176, 347, 2429, 2177, 2445, 2178, 2447, 58, 2480, 390, 452, 554, 555, 313, 92, 275, 335, 428, 167, 302, 2173, 1538) GROUP BY playlists.id ORDER BY count(*) desc
Why would my query be working on development but not on production?
Query
#playlist_ids = #playlist.user_ids
#more_playlists = Playlist.joins(:users).where.not('playlists.id = ? OR playlists.id = ?', 30, 41).where(users: {id: #playlist_ids}).group('playlists.id').order('count(*) desc')
Assocations:
class Playlist < ActiveRecord::Base
has_many :playlist_users
has_many :users, :through => :playlist_users
end
class PlaylistUser < ActiveRecord::Base
belongs_to :playlist
belongs_to :user
end
class User < ActiveRecord::Base
has_many :playlist_users
has_many :playlists, :through => :playlist_users
end
UPDATE
This is pretty strange, I added Playlist.name to the GROUP BY as per trincot's suggestion:
#playlist_ids = #playlist.user_ids
Playlist.select('playlists.id, playlists.name')
.joins(:playlist_users)
.where('playlists.id NOT IN (30, 41)')
.where(playlist_users: {user_id: #playlist_ids})
.group('playlists.id, playlists.name')
.order('count(*) desc')
But I'm getting back a similar error, except now it's telling me I have to include thePlaylist attribute subject_id in the GROUP BY clause:
PG::GroupingError: ERROR: column "playlists.subject_id" must appear in the GROUP BY clause or be used in an aggregate function
But I didn't reference subject_id literally anywhere in my query, or even in the model, controller, or view for the page. Why on earth would that column even be involved in this?
Your statement is not valid according to the PostgreSQL documentation:
When GROUP BY is present, it is not valid for the SELECT list expressions to refer to
ungrouped columns except within aggregate functions, since there would be more than one
possible value to return for an ungrouped column.
If you say it works in your development environment, it must mean that environment has another database engine (version) running.
You should use a statement like this, where the list of fields in the SELECT clause is the same as the list given in the GROUP BY clause:
SELECT playlists.id, playlists.name, ...
FROM playlists
INNER JOIN playlist_users ON playlist_users.playlist_id = playlists.id
WHERE playlists.id NOT IN (30, 41)
AND playlist_users.user_id IN (your_long_list_comes_here)
GROUP BY playlists.id, playlists.name, ...
ORDER BY count(*) desc
Note that you don't actually need to join the users table for the result of your interest, so I removed it and replaced the test on user_id accordingly. Also, the condition on the playlists.id is expressed more concise using the IN operator.
The corresponding Active Record query would be:
Playlist.joins(:playlist_users)
.where('playlists.id NOT IN (30, 41)')
.where(playlist_users: {user_id: #playlist_ids})
.select('playlists.id, playlists.name')
.group('playlists.id, playlists.name')
.order('count(*) desc')
You have to add any other fields you need in both the select and group arguments.

Postgresql Grouping Error refers to a column that was never referenced in the query

I have a model "Playlist" which has_many and belongs_to another model "User", through an intermediary model "PlaylistUser". "Playlist" has several attributes including id, name, and subject_id.
I'm trying to get this query to work:
#playlist_ids = #playlist.user_ids
#more = Playlist.select('playlists.id, playlists.name')
.joins(:playlist_users)
.where('playlists.id NOT IN (30, 41)')
.where(playlist_users: {user_id: #playlist_ids})
.group('playlists.id, playlists.name')
.order('count(*) desc')
which, for a given Playlist #playlist, is supposed to list all the other Playlists that share a User with #playlist, ordered by how many they share.
It works on Postgres 9.4, but with Postgres 8.4 it returns this error:
PG::GroupingError: ERROR: column "playlists.subject_id" must appear in the GROUP BY clause or be used in an aggregate function
LINE 1: SELECT "playlists".* FROM "playlists" INNER JOIN "playlist...
^
: SELECT "playlists".* FROM "playlists" INNER JOIN "playlist_users" ON "playlist_users"."playlist_id" = "playlists"."id" INNER JOIN "users" ON "users"."id" = "playlist_users"."user_id" WHERE (NOT (playlists.id = 30 OR playlists.id = 41)) AND "users"."id" IN (45, 89, 71, 117, 115, 173, 177, 180, 161, 220, 223, 199, 221, 239, 204, 205, 206, 207, 211, 261, 282, 284, 286, 251, 252, 255, 310, 311, 315, 318, 307, 362, 319, 306, 289, 316, 305, 321, 322, 330, 333, 292, 294, 304, 300, 340, 341, 342, 343, 405, 406, 410, 408, 409, 407, 413, 416, 417, 418, 425, 427, 392, 401, 403, 445, 446, 449, 450, 379, 456, 451, 454, 459, 437, 442, 444, 496, 501, 518, 548, 549, 533, 553, 1112, 1113, 1459, 455, 348, 1458, 242, 1275, 151, 1890, 336, 203, 404, 166, 453, 114, 157, 285, 448, 447, 443, 550, 2167, 2168, 287, 320, 293, 65, 2098, 2097, 2099, 387, 3, 2175, 2170, 2174, 2182, 2171, 438, 2180, 2181, 2169, 2176, 347, 2429, 2177, 2445, 2178, 2447, 58, 2480, 390, 452, 554, 555, 313, 92, 275, 335, 428, 167, 302, 2173, 1538) GROUP BY playlists.id, playlists.name ORDER BY count(*) desc
But I'm not referencing the column subject_id anywhere in my query, or anywhere in the view, controller, or model for the page I'm on.
Why would that column have anything to do with whether my query works or not?
Assocations:
class Playlist < ActiveRecord::Base
has_many :playlist_users
has_many :users, :through => :playlist_users
end
class PlaylistUser < ActiveRecord::Base
belongs_to :playlist
belongs_to :user
end
class User < ActiveRecord::Base
has_many :playlist_users
has_many :playlists, :through => :playlist_users
end
Maybe you are not referencing subject_id explicitly but your result query uses:
SELECT "playlists".* FROM "playlists"
And because of the wildcard * you are getting all of the columns in playlist, which includes playlists.subject_id.
You will have to add that column to the group_by clause as well as any others that are grabbed by the wildcard SELECT.

Selecting ID in a certain order specified within IN operator

I would like to try to select a certain set of numbers in a particular order, for use with loops.
SELECT ID
FROM filter
WHERE id in (87, 97, 117, 52, 240, 76, 141, 137, 157, 255, 186, 196, 133,
175, 153, 224, 59, 205, 65, 47, 105, 80, 113, 293, 161, 145,
192, 149, 231, 91, 101, 109, 215, 121, 125, 64, 41, 291, 367,
388, 391, 462, 467)
Doing this returns results sorted by ID, rather than in the order I specified. In most other similar questions a preferred answer was using CASE for particular entries, but what about selecting hundreds of records in a predetermined order?
If you have hundreds of items, then use a derived table, such as:
select f.id
from filter f join
(values(1, 87), (2, 97), (3, 117), . . .) as v(ord, id)
on f.id = v.id
order by ord;