获取非重复值计数大于指定值的列
Get columns with distinct value counts greater than a specified value
想象以下 Python Pandas 数据框:
df = pd.DataFrame({'id' : ['foo', 'bar', 'foo'], \
'A' : ['property1', 'property1', 'property2'], \
'B' : ['test', 'test', 'test'] })
from tabulate import tabulate
print(tabulate(df, headers='keys', tablefmt='psql'))
+----+-----------+------+------+
| | A | B | id |
|----+-----------+------+------|
| 0 | property1 | test | foo |
| 1 | property1 | test | bar |
| 2 | property2 | test | foo |
+----+-----------+------+------+
在这里你可以看到对于 id "foo" 列 B 只有一个唯一(不同的)值,即 test.但对于 A 列,它有两个不同的值 property1 和 property2。对于 id "bar" 两列只有一个不同的值。
如果按 id 分组,我正在寻找的代码可以为我提供那些计数大于 1 的列的名称。所以结果应该是列 A 的名称,因为它包含非不同的值。
df.groupby(['id'])
我只知道如何获取计数(出现)大于 1 的 ID。但这不是我最终要寻找的。
df['id'].value_counts().reset_index(name="count").query("count > 1")["id"]
感谢任何提示。
使用:
#filter column of interest
a = (df.groupby(['id'])['A','B'].nunique() > 1).any()
print (a)
A True
B False
dtype: bool
#if need test all columns without id
a = (df.set_index('id').groupby('id').nunique() > 1).any()
print (a)
A True
B False
dtype: bool
最后一个过滤器:
b = a.index[a]
print (b)
Index(['A'], dtype='object')
也许您正在寻找:
g = df.groupby('id')['A', 'B'].nunique()
g
A B
id
bar 1 1
foo 2 1
要获取相关列,只需索引到 df.columns
:
df.columns[(g > 1).any()]
Index(['A'], dtype='object')
更新:
In [98]: df.columns.drop('id')[(df.groupby('id')[df.columns.drop('id')].nunique() > 1).any()]
Out[98]: Index(['A'], dtype='object')
In [31]: df[['A','B']].columns[df.groupby(['id'])['A','B'].apply(lambda x: x.nunique().gt(1)).any()]
Out[31]: Index(['A'], dtype='object')
解释:
In [32]: df.groupby(['id'])['A','B'].apply(lambda x: x.nunique().gt(1))
Out[32]:
A B
id
bar False False
foo True False
In [33]: df.groupby(['id'])['A','B'].apply(lambda x: x.nunique().gt(1)).any()
Out[33]:
A True
B False
dtype: bool
这是另一种方式
pd.crosstab(df.id,[df.A,df.B],margins =True)
Out[206]:
A property1 property2 All
B test test
id
bar 1 0 1
foo 1 1 2
All 2 1 3
或者类似
[x if df.groupby(['id',x]).ngroup().max()>1 else np.nan for x in df.columns]
Out[233]: ['A', nan, nan]
想象以下 Python Pandas 数据框:
df = pd.DataFrame({'id' : ['foo', 'bar', 'foo'], \
'A' : ['property1', 'property1', 'property2'], \
'B' : ['test', 'test', 'test'] })
from tabulate import tabulate
print(tabulate(df, headers='keys', tablefmt='psql'))
+----+-----------+------+------+
| | A | B | id |
|----+-----------+------+------|
| 0 | property1 | test | foo |
| 1 | property1 | test | bar |
| 2 | property2 | test | foo |
+----+-----------+------+------+
在这里你可以看到对于 id "foo" 列 B 只有一个唯一(不同的)值,即 test.但对于 A 列,它有两个不同的值 property1 和 property2。对于 id "bar" 两列只有一个不同的值。
如果按 id 分组,我正在寻找的代码可以为我提供那些计数大于 1 的列的名称。所以结果应该是列 A 的名称,因为它包含非不同的值。
df.groupby(['id'])
我只知道如何获取计数(出现)大于 1 的 ID。但这不是我最终要寻找的。
df['id'].value_counts().reset_index(name="count").query("count > 1")["id"]
感谢任何提示。
使用:
#filter column of interest
a = (df.groupby(['id'])['A','B'].nunique() > 1).any()
print (a)
A True
B False
dtype: bool
#if need test all columns without id
a = (df.set_index('id').groupby('id').nunique() > 1).any()
print (a)
A True
B False
dtype: bool
最后一个过滤器:
b = a.index[a]
print (b)
Index(['A'], dtype='object')
也许您正在寻找:
g = df.groupby('id')['A', 'B'].nunique()
g
A B
id
bar 1 1
foo 2 1
要获取相关列,只需索引到 df.columns
:
df.columns[(g > 1).any()]
Index(['A'], dtype='object')
更新:
In [98]: df.columns.drop('id')[(df.groupby('id')[df.columns.drop('id')].nunique() > 1).any()]
Out[98]: Index(['A'], dtype='object')
In [31]: df[['A','B']].columns[df.groupby(['id'])['A','B'].apply(lambda x: x.nunique().gt(1)).any()]
Out[31]: Index(['A'], dtype='object')
解释:
In [32]: df.groupby(['id'])['A','B'].apply(lambda x: x.nunique().gt(1))
Out[32]:
A B
id
bar False False
foo True False
In [33]: df.groupby(['id'])['A','B'].apply(lambda x: x.nunique().gt(1)).any()
Out[33]:
A True
B False
dtype: bool
这是另一种方式
pd.crosstab(df.id,[df.A,df.B],margins =True)
Out[206]:
A property1 property2 All
B test test
id
bar 1 0 1
foo 1 1 2
All 2 1 3
或者类似
[x if df.groupby(['id',x]).ngroup().max()>1 else np.nan for x in df.columns]
Out[233]: ['A', nan, nan]