重塑 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.
没有魔法可以解决这个问题,因为你的数据很乱。如果该行未标记为 name
、address
、telephone
和 email
,则 designation
标签是备用标签。所以很有可能,你有多行标记为同一个人 designation
。
在此步骤结束时,使用此命令检查是否有重复项 (person/label -> index/column):
df.value_counts(['index', 'column']).loc[lambda x: x > 1]
可能(我希望你也一样),输出应该仅在 column
列下显示 designation
标签,除非一个人可以有多个 telephone
或 email
。现在您可以调整 condlist
以捕捉最大的模式。我对你的数据一无所知,所以帮不了你太多。
我有这样的数据框。
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 | |
---|---|---|---|---|
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.
没有魔法可以解决这个问题,因为你的数据很乱。如果该行未标记为 name
、address
、telephone
和 email
,则 designation
标签是备用标签。所以很有可能,你有多行标记为同一个人 designation
。
在此步骤结束时,使用此命令检查是否有重复项 (person/label -> index/column):
df.value_counts(['index', 'column']).loc[lambda x: x > 1]
可能(我希望你也一样),输出应该仅在 column
列下显示 designation
标签,除非一个人可以有多个 telephone
或 email
。现在您可以调整 condlist
以捕捉最大的模式。我对你的数据一无所知,所以帮不了你太多。