我正在使用具有以下结构的DataFrame学习Python /熊猫:
import pandas as pd
df = pd.DataFrame({"cus_id" : ["2370", "2370", "5100", "5100", "8450", "8450", "1630", "1630", "1630"],
"cus_group" : ["A", "A", "A", "B", "B", "B", "A", "A", "B"]})
print(df)
cus_id cus_group
0 2370 A
1 2370 A
2 5100 A
3 5100 B
4 8450 B
5 8450 B
6 1630 A
7 1630 A
8 1630 B
我的目标是过滤上述DataFrame的行。具体来说,我只想保留客户属于不同组的行。这是我的尝试:
print(df.drop_duplicates(subset = ["cus_id", "cus_group"], keep = False))
cus_id cus_group
2 5100 A
3 5100 B
8 1630 B
不幸的是,这不是我想要的确切输出。请注意,cus_id
= 1630
在原始DataFrame中出现3次:在A
组中两次,在B
组中一次。由于它属于两个不同的组(A
和B
),因此我不想删除该客户的任何行。也就是说,我正在寻找的输出如下:
cus_id cus_group
2 5100 A
3 5100 B
6 1630 A
7 1630 A
8 1630 B
我不确定要实现我的目标需要缺少哪些功能。任何其他帮助将不胜感激。
答案 0 :(得分:1)
将groupby
和transform
用作nunique
,这样可以将唯一计数作为系列,然后仅过滤大于1的数字:
df[df.groupby('cus_id')['cus_group'].transform('nunique')>1]
cus_id cus_group
2 5100 A
3 5100 B
6 1630 A
7 1630 A
8 1630 B
答案 1 :(得分:1)
将DataFrameGroupBy.nunique
与GroupBy.transform
一起用于plt.figure(figsize=(15,10))
H = ceil(sqrt(len(good_images)))
W = 1+len(good_images)//ceil(sqrt(len(good_images)))
print(len(good_images),H, W)
for i,im in enumerate(good_images):
plt.subplot(H, W, i+1,xticks=[],yticks=[])
plt.title(im.shape)
plt.imshow(im, interpolation='nearest', cmap=plt.cm.gist_gray_r)
,其大小与原始DataFrame相同,因此可能用boolean indexing
过滤不相等的Series
行:
1
详细信息:
df = df[df.groupby('cus_id')['cus_group'].transform('nunique').ne(1)]
print (df)
cus_id cus_group
2 5100 A
3 5100 B
6 1630 A
7 1630 A
8 1630 B
答案 2 :(得分:1)
或使用pandas.DataFrame.groupby.filter
:
df.groupby('cus_id').filter(lambda x: x['cus_group'].nunique()>1)
输出:
cus_group cus_id
2 A 5100
3 B 5100
6 A 1630
7 A 1630
8 B 1630
答案 3 :(得分:1)
您只需将保留价值更改为第一。它会给您想要的结果。
import pandas as pd
df = pd.DataFrame({"cus_id" : ["2370", "2370", "5100", "5100", "8450", "8450", "1630", "1630", "1630"],
"cus_group" : ["A", "A", "A", "B", "B", "B", "A", "A", "B"]})
print(df.drop_duplicates(subset = ["cus_id", "cus_group"], keep = "first"))
编辑
我很抱歉,我误解了这个问题
您可以使用group_by
进行识别,然后将transform作为nunique
使用以提供结果。
答案 4 :(得分:1)
它还可以与filter
,duplicated
和any
df.groupby('cus_id').filter(lambda x: (~x.cus_group.duplicated(keep=False)).any())
Out[510]:
cus_id cus_group
2 5100 A
3 5100 B
6 1630 A
7 1630 A
8 1630 B