将函数应用于组中的第一个元素,然后合并

时间:2019-08-15 13:42:51

标签: python python-3.x pandas

(对不起,我意识到标题不是很具描述性)

给出如下数据集:

       word  entity
0   Charlie      1
1        p.      1
2    Nelson      1
3     loves   None
4      Dana      2
5        c.      2
6  anderson      2
7       and   None
8     james      3

我想将一个函数(例如get_gender())应用于每个实体的第一个元素(我想我会以某种方式进行分组)

要得到这样的东西:

       word entity gender
0   Charlie      1      m
1        p.      1   None
2    Nelson      1   None
3     loves   None   None
4      Dana      2      f
5        c.      2   None
6  anderson      2   None
7       and   None   None
8     james      3      m

最后填充每个实体的缺失行以获取

       word entity gender
0   Charlie      1      m
1        p.      1      m
2    Nelson      1      m
3     loves   None   None
4      Dana      2      f
5        c.      2      f
6  anderson      2      f
7       and   None   None
8     james      3      m

以下是用于生成上述数据帧的代码

import pandas as pd
df  = pd.DataFrame([("Charlie", "p.", "Nelson", "loves", "Dana", "c.", "anderson", "and", "james"), (1,1,1, None, 2,2,2, None, 3)]).transpose()
df.columns = ["word", "entity"]

我正在使用的当前“解决方案”是:

import gender_guesser.detector as gender
d = gender.Detector() 
# Detect gender in of the names in word. However this one if applied to all of the entity (including last names, furthermore one entity can be multiple genders (depending on e.g. their middle name)
df['gender'].loc[(df['entity'].isnull() == False)] = df['word'].loc[(df['entity'].isnull() == False)].apply(lambda string: d.get_gender(string.lower().capitalize()))

1 个答案:

答案 0 :(得分:0)

groupby之后没有顺序,因此您无法从组中获取 first 元素。在这种情况下,您可以按实体分组,然后从每个组中选择not值,然后与原始DataFrame合并。

df  = pd.DataFrame([
    ("Charlie", "p.", "Nelson", "loves", "Dana", "c.", "anderson", "and", "james")
    , (1,1,1, None, 2,2,2, None, 3)
    , ('m', None, None, None, 'f', None, None, None, 'm')]).transpose()
df.columns = ["word", "entity", "gender"]

df_g = df.groupby('entity').agg({'gender': lambda x: max(filter(None, x))}).reset_index()

pd.merge(df, df_g, on='entity', suffixes=('_x', ''))[['word', 'entity', 'gender']]

但是请注意,在groupby之后,实体None的项目消失了。