假设我有一个看起来像这样的DataFrame:
df=pd.DataFrame({'name': ['john','jack','jill','al','zoe','jenn','ringo','paul','george','lisa'], 'how do you feel?': ['excited', 'not excited', 'excited and nervous', 'worried', 'really worried', 'excited', 'not that worried', 'not that excited', 'nervous', 'nervous']})
how do you feel? name
0 excited john
1 not excited jack
2 excited and nervous jill
3 worried al
4 really worried zoe
5 excited jenn
6 not that worried ringo
7 not that excited paul
8 nervous george
9 nervous lisa
我对计数很感兴趣,但分为三个类别:“兴奋”,“担心”和“紧张”。
要注意的是,“激动和紧张”应该与“激动”分组。实际上,对于“不那么兴奋”和“不那么兴奋”之类的字符串,应将包含“激发”的字符串包含在组 中。相同的逻辑适用于“担心”和“紧张”。 (请注意,“兴奋和紧张”实际上属于“兴奋”和“紧张”组)
您会看到典型的groupby无法正常工作,并且字符串搜索必须灵活。
我有一个解决方案,但想知道是否所有人都可以找到更好的方法来成为Python语言,并且/或者使用我可能不知道的更合适的方法。
定义一个函数以返回包含所需子字符串且不包含否定情绪的子字符串的行的计数
def get_perc(df, column_label, str_include, str_exclude):
data=df[col_lab][(~df[col_lab].str.contains(str_exclude, case=False)) & \
(df[col_lab].str.contains(str_include, case=False))]
num=data.count()
return num
然后,在循环内调用此函数,传入各种“ str.contains”参数,然后将结果收集到另一个DataFrame中。
groups=['excited', 'worried', 'nervous']
column_label='How do you feel?'
data=pd.DataFrame([], columns=['group','num'])
for str_include in groups:
num=get_perc(df, column_label, str_include, 'not|neither')
tmp=pd.DataFrame([{'group': str_include,'num': num}])
data=pd.concat([data, tmp])
data
group num
0 excited 3
1 worried 2
2 nervous 3
您能想到一种更清洁的方法吗?我确实尝试过使用“ str.contains
”中的正则表达式来避免使用两个布尔序列和“ &
”。但是,没有捕获组就无法做到这一点,这意味着我不得不使用“ str.extract
”,这似乎不允许我以相同的方式选择数据。
非常感谢您的帮助。
答案 0 :(得分:4)
您可以这样做:
方法1
not
行,然后groups
。In [140]: col = 'how do you feel?'
In [141]: groups = ['excited', 'worried', 'nervous']
In [142]: df.loc[~df[col].str.contains('not '), col].str.get_dummies(sep=' ')[groups].sum()
Out[142]:
excited 3
worried 2
nervous 3
dtype: int64
方法2
In [162]: dfs = df['how do you feel?'].str.get_dummies(sep=' ')
In [163]: dfs.loc[~dfs['not'].astype(bool), groups].sum()
Out[163]:
excited 3
worried 2
nervous 3
dtype: int64
答案 1 :(得分:3)
您可以简单地提供映射,然后按映射产生的新系列进行分组。
map_dict = {'excited and nervous':'excited', 'not that excited':'not excited',
'really worried':'worried', 'not that worried':'not worried'}
df.groupby(df['how do you feel?'].replace(map_dict)).size()
输出:
how do you feel?
excited 3
nervous 2
not excited 2
not worried 1
worried 2
dtype: int64