我有一个巨大的文件(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)
谢谢
最佳答案
您可以将groupby
与apply
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
如果要过滤连接输出中的某些值,请使用
contains
和join
|
(正则表达式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