Count every possible pair of values in a column grouped by multiple columns
Updated: Here is a fast and memory efficient version using data.table
:
Step 1: Construct sample data of your dimensions approximately:
require(data.table) ## 1.9.4+
set.seed(1L) ## For reproducibility
N = 2724098L
motif = sample(paste("motif", 1:1716, sep="_"), N, TRUE)
id = sample(83509, N, TRUE)
DT = data.table(id, motif)Step 2: Pre-processing:
DT = unique(DT) ## IMPORTANT: not to have duplicate motifs within same id
setorder(DT) ## IMPORTANT: motifs are ordered within id as well
setkey(DT, id) ## reset key to 'id'. Motifs ordered within id from previous step
DT[, runlen := .I]Step 3: Solution:
ans = DT[DT, {
tmp = runlen < i.runlen;
list(motif[tmp], i.motif[any(tmp)])
},
by=.EACHI][, .N, by="V1,V2"]This takes ~27 seconds and ~1GB of memory during the final step 3.
The idea is to perform a self-join, but make use of data.table's by=.EACHI
feature, which evaluates the j-expression
for each i
, and therefore memory efficient. And the j-expression
makes sure that we only obtain the entry "motif_a, motif_b" and not the redundant "motif_b,motif_a". This saves computation time and memory as well. And the binary search is quite fast, even though there are 87K+ ids. Finally we aggregate by the motif combinations to get the number of rows in each of them - which is what you require.
HTH
PS: See revision for the older (+ slower) version.
Group by two columns and count the occurrences of each combination in Pandas
Maybe this is what you want?
>>> data = pd.DataFrame({'user_id' : ['a1', 'a1', 'a1', 'a2','a2','a2','a3','a3','a3'], 'product_id' : ['p1','p1','p2','p1','p1','p1','p2','p2','p3']})
>>> count_series = data.groupby(['user_id', 'product_id']).size()
>>> count_series
user_id product_id
a1 p1 2
p2 1
a2 p1 3
a3 p2 2
p3 1
dtype: int64
>>> new_df = count_series.to_frame(name = 'size').reset_index()
>>> new_df
user_id product_id size
0 a1 p1 2
1 a1 p2 1
2 a2 p1 3
3 a3 p2 2
4 a3 p3 1
>>> new_df['size']
0 2
1 1
2 3
3 2
4 1
Name: size, dtype: int64
Pandas DataFrame Groupby two columns and get counts
Followed by @Andy's answer, you can do following to solve your second question:
In [56]: df.groupby(['col5','col2']).size().reset_index().groupby('col2')[[0]].max()
Out[56]:
0
col2
A 3
B 2
C 1
D 3
Using group by on multiple columns
Group By X
means put all those with the same value for X in the one group.
Group By X, Y
means put all those with the same values for both X and Y in the one group.
To illustrate using an example, let's say we have the following table, to do with who is attending what subject at a university:
Table: Subject_Selection
+---------+----------+----------+
| Subject | Semester | Attendee |
+---------+----------+----------+
| ITB001 | 1 | John |
| ITB001 | 1 | Bob |
| ITB001 | 1 | Mickey |
| ITB001 | 2 | Jenny |
| ITB001 | 2 | James |
| MKB114 | 1 | John |
| MKB114 | 1 | Erica |
+---------+----------+----------+
When you use a group by
on the subject column only; say:
select Subject, Count(*)
from Subject_Selection
group by Subject
You will get something like:
+---------+-------+
| Subject | Count |
+---------+-------+
| ITB001 | 5 |
| MKB114 | 2 |
+---------+-------+
...because there are 5 entries for ITB001, and 2 for MKB114
If we were to group by
two columns:
select Subject, Semester, Count(*)
from Subject_Selection
group by Subject, Semester
we would get this:
+---------+----------+-------+
| Subject | Semester | Count |
+---------+----------+-------+
| ITB001 | 1 | 3 |
| ITB001 | 2 | 2 |
| MKB114 | 1 | 2 |
+---------+----------+-------+
This is because, when we group by two columns, it is saying "Group them so that all of those with the same Subject and Semester are in the same group, and then calculate all the aggregate functions (Count, Sum, Average, etc.) for each of those groups". In this example, this is demonstrated by the fact that, when we count them, there are three people doing ITB001 in semester 1, and two doing it in semester 2. Both of the people doing MKB114 are in semester 1, so there is no row for semester 2 (no data fits into the group "MKB114, Semester 2")
Hopefully that makes sense.
Group by and count unique values in several columns in R
Here's an approach using dplyr::across
, which is a handy way to calculate across multiple columns:
my_data <- data.frame(
city = c(rep("A", 3), rep("B", 3)),
col1 = 1:6,
col2 = 0,
col3 = c(1:3, 4, 4, 4),
col4 = 1:2
)
library(dplyr)
my_data %>%
group_by(city) %>%
summarize(across(col1:col4, n_distinct))
# A tibble: 2 x 5
city col1 col2 col3 col4
* <chr> <int> <int> <int> <int>
1 A 3 1 3 2
2 B 3 1 1 2
Python: get a frequency count based on two columns (variables) in pandas dataframe some row appers
You can use groupby's size
:
In [11]: df.groupby(["Group", "Size"]).size()
Out[11]:
Group Size
Moderate Medium 1
Small 1
Short Small 2
Tall Large 1
dtype: int64
In [12]: df.groupby(["Group", "Size"]).size().reset_index(name="Time")
Out[12]:
Group Size Time
0 Moderate Medium 1
1 Moderate Small 1
2 Short Small 2
3 Tall Large 1
Pandas - dataframe groupby - how to get sum of multiple columns
By using apply
df.groupby(['col1', 'col2'])["col3", "col4"].apply(lambda x : x.astype(int).sum())
Out[1257]:
col3 col4
col1 col2
a c 2 4
d 1 2
b d 1 2
e 2 4
If you want to agg
df.groupby(['col1', 'col2']).agg({'col3':'sum','col4':'sum'})
Group By 2 columns and Count then Sort the count for each key pair
I think you want two sort keys:
ORDER BY device, times DESC;
If you want to sort the devices as well, so the biggest device is first, you can use window functions:
ORDER BY sum(times) over (partition by device) DESC, device, times DESC
Counting DISTINCT over multiple columns
If you are trying to improve performance, you could try creating a persisted computed column on either a hash or concatenated value of the two columns.
Once it is persisted, provided the column is deterministic and you are using "sane" database settings, it can be indexed and / or statistics can be created on it.
I believe a distinct count of the computed column would be equivalent to your query.
Related Topics
How to Select Columns Programmatically in a Data.Table
Two Horizontal Bar Charts with Shared Axis in Ggplot2 (Similar to Population Pyramid)
Dplyr Summarise Multiple Columns Using T.Test
R - Ggplot2 - Highlighting Selected Points and Strange Behavior
How to Add a Page Break in Word Document Generated by Rstudio & Markdown
How to Change the Now Deprecated Dplyr::Funs() Which Includes an Ifelse Argument
Subset Rows According to a Range of Time
Remove 'Search' Option But Leave 'Search Columns' Option
Sum of Two Columns of Data Frame with Na Values
Coloring Boxplot Outlier Points in Ggplot2
Create Barplot from Data.Frame
Collapse All Columns by an Id Column
How to Create a Bar Plot for Two Variables Mirrored Across the X-Axis in R
How to Pass Multiple Arguments to a Function as a Single Vector