我在pandas中有数据框:
In [10]: df
Out[10]:
col_a col_b col_c col_d
0 France Paris 3 4
1 UK Londo 4 5
2 US Chicago 5 6
3 UK Bristol 3 3
4 US Paris 8 9
5 US London 44 4
6 US Chicago 12 4
我需要统计独特的城市。我可以数独特的状态
In [11]: df['col_a'].nunique()
Out[11]: 3
我可以尝试计算独特的城市
In [12]: df['col_b'].nunique()
Out[12]: 5
但这是错误的,因为法国的美国巴黎和巴黎是不同的城市。所以现在我这样做:
In [13]: df['col_a_b'] = df['col_a'] + ' - ' + df['col_b']
In [14]: df
Out[14]:
col_a col_b col_c col_d col_a_b
0 France Paris 3 4 France - Paris
1 UK Londo 4 5 UK - Londo
2 US Chicago 5 6 US - Chicago
3 UK Bristol 3 3 UK - Bristol
4 US Paris 8 9 US - Paris
5 US London 44 4 US - London
6 US Chicago 12 4 US - Chicago
In [15]: df['col_a_b'].nunique()
Out[15]: 6
也许有更好的方法?无需创建其他列。
答案 0 :(得分:17)
使用ngroups
df.groupby(['col_a', 'col_b']).ngroups
Out[101]: 6
或使用set
len(set(zip(df['col_a'],df['col_b'])))
Out[106]: 6
答案 1 :(得分:6)
您可以选择 col_a 和 col_b ,删除重复项,然后检查结果数据框的 shape / len :
FancyFoo
因为df[['col_a', 'col_b']].drop_duplicates().shape[0]
# 6
len(df[['col_a', 'col_b']].drop_duplicates())
# 6
忽略了groupby
,并且可能会不必要地调用排序过程,所以如果列中有NaN
,请相应选择使用哪种方法:
考虑如下数据框:
NaN
时序:
df = pd.DataFrame({
'col_a': [1,2,2,pd.np.nan,1,4],
'col_b': [2,2,3,pd.np.nan,2,pd.np.nan]
})
print(df)
# col_a col_b
#0 1.0 2.0
#1 2.0 2.0
#2 2.0 3.0
#3 NaN NaN
#4 1.0 2.0
#5 4.0 NaN
结果:
df = pd.concat([df] * 1000)
%timeit df.groupby(['col_a', 'col_b']).ngroups
# 1000 loops, best of 3: 625 µs per loop
%timeit len(df[['col_a', 'col_b']].drop_duplicates())
# 1000 loops, best of 3: 1.02 ms per loop
%timeit df[['col_a', 'col_b']].drop_duplicates().shape[0]
# 1000 loops, best of 3: 1.01 ms per loop
%timeit len(set(zip(df['col_a'],df['col_b'])))
# 10 loops, best of 3: 56 ms per loop
%timeit len(df.groupby(['col_a', 'col_b']))
# 1 loop, best of 3: 260 ms per loop
所以差异:
选项1:
df.groupby(['col_a', 'col_b']).ngroups
# 3
len(df[['col_a', 'col_b']].drop_duplicates())
# 5
df[['col_a', 'col_b']].drop_duplicates().shape[0]
# 5
len(set(zip(df['col_a'],df['col_b'])))
# 2003
len(df.groupby(['col_a', 'col_b']))
# 2003
很快,它排除了包含df.groupby(['col_a', 'col_b']).ngroups
s。
选项2& 3:
NaN
合理地快,它将len(df[['col_a', 'col_b']].drop_duplicates())
df[['col_a', 'col_b']].drop_duplicates().shape[0]
s视为唯一值。
选项4& 5:
NaN
很慢,并且它遵循len(set(zip(df['col_a'],df['col_b'])))
len(df.groupby(['col_a', 'col_b']))
为假的逻辑,因此不同的(nan,nan)行被认为是不同的。
答案 2 :(得分:4)
In [105]: len(df.groupby(['col_a', 'col_b']))
Out[105]: 6
答案 3 :(得分:0)
试试这个,我基本上从df中的行数中减去重复组的数量。这假设我们正在对df中的所有类别进行分组
if let
var theError = nil
if let error = myError {
// because you hard coded the value of error to be "None" return nil instead
// else return the actual value of the error
if error == "None" { return theError } else {
theError = error
print("error has a value! ", error.localizedDescription)
}
} else {
print("There is no error")
}
return theError // returns nil instead of "None" or it returns a real error
答案 4 :(得分:0)
import pandas as pd
data = {'field1':[1,4,1,68,9],'field2':[1,1,4,5,9]}
df = pd.DataFrame(data)
results = df.groupby('field1')['field2'].nunique()
results
输出:
field1
1 2
4 1
9 1
68 1
Name: field2, dtype: int64