【问题标题】:Reshape python dataframe重塑python数据框
【发布时间】:2021-12-02 21:07:48
【问题描述】:

我有这样的数据框。

description
Brian
No.22
Tel:+00123456789
email:brain@email.com
Sandra
No:43
Tel:+00312456789
Michel
No:593
Kent
No:13
Engineer
Tel:04512367890
email:kent@yahoo.com

我想要这样。

name address designation telephone email
Brian No:22 null Tel:+00123456789 email:brain@email.com
Sandra No:43 null Tel:+00312456789 null
Michel No:593 null null null
Kent No:13 Engineer Tel:04512367890 email:kent@yahoo.com

如何在 python 中做到这一点。

【问题讨论】:

    标签: python pandas dataframe reshape


    【解决方案1】:

    使用np.where 标记每一行,然后使用pivot 标记您的数据框。

    第 1 步。

    condlist = [df['description'].shift(fill_value='').eq(''),
                df['description'].str.contains('^No[:.]'),
                df['description'].str.startswith('Tel:'),
                df['description'].str.startswith('email:')]
    choicelist = ['name', 'address', 'telephone', 'email']
    df['column'] = np.select(condlist, choicelist, default='designation')
    print(df)
    
    # Output:
                  description       column
    0                   Brian         name
    1                   No.22      address
    2        Tel:+00123456789    telephone
    3   email:brain@email.com        email
    4                          designation
    5                  Sandra         name
    6                   No:43      address
    7        Tel:+00312456789    telephone
    8                          designation
    9                  Michel         name
    10                 No:593      address
    11                         designation
    12                   Kent         name
    13                  No:13      address
    14               Engineer  designation
    15        Tel:04512367890    telephone
    16   email:kent@yahoo.com        email
    

    第 2 步。 现在删除空行并创建索引以允许枢轴:

    df = df[df['description'].ne('')].assign(index=df['column'].eq('name').cumsum())
    print(df)
    
    # Output:
                  description       column  index
    0                   Brian         name      1
    1                   No.22      address      1
    2        Tel:+00123456789    telephone      1
    3   email:brain@email.com        email      1
    5                  Sandra         name      2
    6                   No:43      address      2
    7        Tel:+00312456789    telephone      2
    9                  Michel         name      3
    10                 No:593      address      3
    12                   Kent         name      4
    13                  No:13      address      4
    14               Engineer  designation      4
    15        Tel:04512367890    telephone      4
    16   email:kent@yahoo.com        email      4
    

    第 3 步。 旋转您的数据框:

    cols = ['name', 'address', 'designation', 'telephone', 'email']
    out = df.pivot('index', 'column', 'description')[cols] \
            .rename_axis(index=None, columns=None)
    print(out)
    
    # Output:
         name address designation         telephone                  email
    1   Brian   No.22         NaN  Tel:+00123456789  email:brain@email.com
    2  Sandra   No:43         NaN  Tel:+00312456789                    NaN
    3  Michel  No:593         NaN               NaN                    NaN
    4    Kent   No:13    Engineer   Tel:04512367890   email:kent@yahoo.com
    

    编辑

    最后一步出现错误“ValueError:索引包含重复条目,无法重塑”我该如何克服这个问题。

    没有什么魔法可以解决这个问题,因为你的数据很乱。如果行未标记为nameaddresstelephoneemail,则designation 标签是备用标签。所以很有可能,同一个人有多个标记为 designation 的行。

    在此步骤结束时,使用此命令检查您是否有重复项(人/标签 -> 索引/列):

    df.value_counts(['index', 'column']).loc[lambda x: x > 1]
    

    可能(我希望你也这样),输出应该只在column 列下显示designation 标签,除非一个人可以拥有多个telephoneemail。现在您可以调整condlist 以捕捉最大的模式。我对您的数据一无所知,因此无法为您提供太多帮助。

    【讨论】:

    • Corralien,非常感谢您,这是一个很大的帮助。你的步骤很清楚。但是当我将您的步骤应用于实际时,最后一步出现错误“ValueError:索引包含重复的条目,无法重塑”我该如何克服这个..请帮助我..
    • 您的数据的问题是所有内容都没有标签获取默认标签designation,因为我们无法识别任何模式来标记条目。因此,如果对于一个组(索引),您有许多标签(列),pivot 将引发异常,因为它不知道如何处理重复的单元格(索引/列)。
    • 是否可以删除重复索引以及如何删除。谢谢
    • 试试:out = df.drop_duplicates(['index', 'column']).pivot('index', 'column', 'description')[cols].rename_axis(index=None, columns=None)
    • 按照您的指示,我删除了重复项,它起作用了..非常感谢..
    猜你喜欢
    • 2020-02-25
    • 1970-01-01
    • 2020-04-19
    • 1970-01-01
    • 2023-02-04
    • 2013-01-27
    • 2015-10-07
    相关资源
    最近更新 更多