我有一个巨大的文件(50,000行),带有2列(id和name)。一个ID可以有不同的名称,但我只在寻找特定的名称及其ID。这个特定的名称可能彼此有任何组合,我需要检查整个文件中是否有任何组合。
我写了下面的函数,它不会给我任何错误,但是它都不起作用。

我也想计算这些名称的任何组合。

顺便说一下,我正在使用熊猫并将数据作为数据框导入。

例如:

id  name
a    TD
a    NB
a    LB
b    LR
b    NB
c    LR
c    NB
d    LB


我想要这样的结果:

a  TD,NB,LR  # they might have any combination I just wrote them as example
b  NB,LR
c  NB,LR
d  LB


为了计数,我想要:

TD,NB,LR 1
NB,LR    2
LB       1


def Gene_count(df_file):
    df_group_id = df.groupby('id').name
    for j in df_group_id:
            j = df.id
    for i in df_group_id:
    if i == 'TD' or i=='NB' or i=='LR' or i== 'LB':
                 print(i,j)


谢谢

最佳答案

您可以将groupbyapply join一起使用:

df1 = df.groupby('id')['name'].apply(','.join)
print (df1)
id
a    TD,NB,LB
b       LR,NB
c       LR,NB
d          LB
Name: name, dtype: object


然后value_counts

print (df1.value_counts())
LR,NB       2
LB          1
TD,NB,LB    1
Name: name, dtype: int64


如果要过滤连接输出中的某些值,请使用containsjoin |(正则表达式or)和boolean indexing

df1 = df.groupby('id')['name'].apply(','.join)

df2 = df1[df1.str.contains('|'.join(['LR','NB']))]
print (df2)
id
a    TD,NB,LB
b       LR,NB
c       LR,NB
Name: name, dtype: object

print (df2.value_counts())
LR,NB       2
TD,NB,LB    1
Name: name, dtype: int64


另一种可能的解决方案是使用double isin之前的filter:

#get all id where is value LR or NB (unique is for better performance)
ids = df.loc[df.name.isin(['LR','NB']), 'id'].unique()
print (ids)
['a' 'b' 'c']

#filter by ids
df3 = df[df.id.isin(ids)]
print (df3)
  id name
0  a   TD
1  a   NB
2  a   LB
3  b   LR
4  b   NB
5  c   LR
6  c   NB

df4 = df3.groupby('id')['name'].apply(','.join)
print (df4)
id
a    TD,NB,LB
b       LR,NB
c       LR,NB
Name: name, dtype: object

print (df4.value_counts())
LR,NB       2
TD,NB,LB    1
Name: name, dtype: int64


我对这两种解决方案的性能都非常感兴趣-一样:

np.random.seed(123)
N = 1000000
L1 = list("abcdefghijklmnopqrstuvwxyz")
df = pd.DataFrame({'id':np.random.choice(L1, N),
                   'name': np.random.choice(L1, N)})

In [31]: %timeit (df.groupby('id')['name'].apply(','.join))
10 loops, best of 3: 130 ms per loop

In [32]: %timeit (df.groupby('id')['name'].apply(lambda x: ','.join(x.tolist())))
10 loops, best of 3: 131 ms per loop

07-24 18:56
查看更多