重塑 python 数据框

Reshape python dataframe

我有这样的数据框。

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 中执行此操作。

使用 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

编辑

There is an error at final step" ValueError: Index contains duplicate entries, cannot reshape" how can I overcome this.

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

在此步骤结束时,使用此命令检查是否有重复项 (person/label -> index/column):

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

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