在包含列的2个和3个字符串子集的列表上执行熊猫松鸡



假设我有一个包含人名的简单数据帧。我在name上执行groupby

import pandas as pd
df = pd.DataFrame({'col1' : [1,2,3,4,5,6,7], 'name': ['George', 'John', 'Tim', 'Joe', 'Issac', 'George', 'Tim'] })
df1 = df.groupby('name')

问题:如何从包含名称的字符串子集(2个或3个字符(的列表中选择特定名称的表?

例如,假设我有以下列表,其中Tim & Geoname列中某些条目的前3个字符,而Joname列中某个条目的前2个字符。

list = ['Jo', 'Tim', 'Geo']

尝试过:我最初的想法是在原始数据帧中创建新列,这些列是name列的2或3个字符的子集,然后尝试按此进行分组,但由于2和3个字符串字符不同,分组不会输出正确的结果。

不确定是否最好使用一些if条件,如if v in list is len(2) groupby(2char) else groupby(3char),并将结果输出为1数据帧。

list
df1['name_2char_subset] = df1['name'].str[0:2]
df1['name_3char_subset] = df1['name'].str[0:3]
if v in list is len(2):
df2 = df1.groupby('name_2char_subset')
else:
df2 = df1.groupby('name_3char_subset')

所需输出:由于Jo、Geo&蒂姆。输出应按每个案例分组。即对于CCD_ 9,两个CCD_。

df3 = pd.DataFrame({'name': ['Jo', 'Tim', 'Geo'], 'col1': [2,2,2]})

我们如何按名称分组并输出name中具有列表中给定初始字符的条目?任何其他方法都会有所帮助。例如,可以在执行分组依据之后,在列表中提取值的分组依据中执行此操作。

首先不要使用list作为变量,因为python代码字。然后使用Series.str.extract通过^开始字符串并在Series.value_counts:中计数来测试是否匹配

L = ['Jo', 'Tim', 'Geo']
pat = '|'.join(r"^{}".format(x) for x in L)
df = (df['name'].str.extract('('+ pat + ')', expand=False)
.dropna()
.value_counts()
.reindex(L, fill_value=0)
.rename_axis('name')
.reset_index(name='col1'))
print (df)
name  col1
0   Jo     2
1  Tim     2
2  Geo     2

您的解决方案:

L = ['Jo', 'Tim', 'Geo']
s1 = df['name'].str[:2]
s2 = df['name'].str[:3]
df = (s1.where(s1.isin(L)).fillna(s2.where(s2.isin(L)))
.dropna()
.value_counts()
.reindex(L, fill_value=0)
.rename_axis('name')
.reset_index(name='col1'))
print (df)
name  col1
0   Jo     2
1  Tim     2
2  Geo     2

如果按列表启动字符串,则通过Series.str.startswith对删除的答案进行更改后的解决方案:

L = ['Jo', 'Tim', 'Geo']
df3 = pd.DataFrame({'name': L})
df3['col1'] = df3['name'].apply(lambda x: sum(df['name'].str.startswith(x)))
print (df3)
name  col1
0   Jo     2
1  Tim     2
2  Geo     2

编辑:如果需要按更多列分组,请使用第一个或第二个解决方案,将列分配回GroupBy.agg:中的名称聚合

df = pd.DataFrame({'age' : [1,2,3,4,5,6,7],
'name': ['George', 'John', 'Tim', 'Joe', 'Issac', 'George', 'Tim'] })
print (df)
L = ['Jo', 'Tim', 'Geo']
pat = '|'.join(r"^{}".format(x) for x in L)
df['name'] = df['name'].str.extract('('+ pat + ')', expand=False)

df = df.groupby('name').agg(sum_age=('age','sum'), col1=('name', 'count'))
print (df)
sum_age  col1
name               
Geo         7     2
Jo          6     2
Tim        10     2

最新更新