pandas 如何合并和拆分DataFrame的行?

vjrehmav  于 2023-01-11  发布在  其他
关注(0)|答案(1)|浏览(173)

我有一个数据框的用户信息,如姓名,邮件,生日,流派...但数据框有重复的用户与重要的不同信息在两行。也有问题,有不同的用户具有相同的名称。例如:
原始 Dataframe

Name Mail          Birthday Genre Subscription Age  Comments
0    A    A@gmail.com   1-1-1990 M     Y            33   -
1    B    None          NaT      F     N            NaN  -
2    C    C@gmail.com   1-1-1985 M     Y            38   -
3    D    None          1-1-1980 I     N            43   - 
4    B    None          1-1-1995 I     N            27   -
5    D    D@gmail.com   NaT      M     Y            NaN  -
6    B    B@gmail.com   NaT      I     Y            NaN  -
7    C    C2@gmail.com  1-1-1970 F     N            53   -

我想要这样的东西:

Name Mail          Birthday Genre Subscription Age Comments
0    A    A@gmail.com   1-1-1990 M     Y            33  -
1    B    B@gmail.com   1-1-1995 F     Y            27  -
2    C    C@gmail.com   1-1-1985 M     Y            38  -
3    D    D@gmail.com   1-1-1980 M     Y            43  -
4    C2   C2@gmail.com  1-1-1970 F     N            53  -

例如,可以按名称分组并合并行,将所有信息保留在一行中,如果一列中的两行具有相同的值,则保留该值。此外,如果两行不同的值具有相同的名称,则使用新名称为其他用户创建一行。
例如中间体DF:

Name Mail            Birthday   Genre Subscription Age   Comments
0    A    A@gmail.com     1-1-1990   M     Y            33    -
1    B    B@gmail.com     1-1-1995   F     Y            27    -
2    C    [C@gmail.com,   [1-1-1985, [M,   [Y,          [38,  [-,
           C2@gmail.com]   1-1-1970]  F]    N]           53]   -]
3    D    D@gmail.com     1-1-1980   M     Y            43    -

我尝试使用groupby函数或join函数,但无法正常工作。
谢谢。

ldioqlga

ldioqlga1#

您可以使用replace values per folumnc for exclude with aggregate by all columns without Name by custom function with reusing variable by walrus operator := with在移除缺失值和重复项后将ene元素列表转换为标量和空列表转换为NaN s来合并值:

f = lambda x: y if (len(y:=list(dict.fromkeys(x.dropna()))) > 1) 
                else y[0] 
                if len(y) != 0 
                else np.nan

df = (df.replace({'Mail':{'None':np.nan},
                  'Birthday':{'NaT':np.nan},
                  'Genre':{'I':np.nan}, 
                  'Subscription':{'N':np.nan}})
        .set_index('Name')
        .groupby('Name')
        .agg(f))
print (df)
                             Mail              Birthday   Genre Subscription  \
Name                                                                           
A                     A@gmail.com              1-1-1990       M            Y   
B                     B@gmail.com              1-1-1995       F            Y   
C     [C@gmail.com, C2@gmail.com]  [1-1-1985, 1-1-1970]  [M, F]            Y   
D                     D@gmail.com              1-1-1980       M            Y   

               Age Comments  
Name                         
A             33.0        -  
B             27.0        -  
C     [38.0, 53.0]        -  
D             43.0        -

相关问题