Pandas:包含变量名称和值的多列:如何使用 Pivot?
Pandas: Multiple columns containing Names and Values of Variables: How to use Pivot?
我不确定是否以及如何进行以下转换:
我有一个如下所示的 DataFrame:
Index Name detail1 detail1_value detail2 detail2_value detail3 detail3_value
1 Albert Age 30 Group A Hometown beautifulplace
2 Bea Age 28 Hometown anotherplace None None
3 Celin Age 45 Group B None None
4 Dave Group A None None None None
不过如你所想,我的目标是:
Index Name Age Group Hometown
1 Albert 30 A beautifulplace
2 Bea 28 anotherplace
3 Celin 45 B
4 Dave A
我很确定每个细节只出现一次。
为了让事情变得复杂:我不确定每个细节是否完全相同(在某些情况下,例如 Hometowns 而不是 Hometown)。
到目前为止我能看到的唯一解决方案是从每对列中生成单个数据透视表(如 detail1 和 detail1_value)。在第二步中,创建一个新数据集,并在例如年龄信息中搜索每个数据透视表。
但是我对 python 的信任告诉我,一定有更好的方法...
谢谢!
PS:
可能有帮助:
dataset = pd.DataFrame({'Name': ['Albert', 'Bea', 'Celine', 'Dave'],
'detail1': ['Age', 'Age', 'Age', 'Group'],
'detail1_value': ['30', '28', '45', 'A'],
'detail2': ['Group', 'Hometown', 'Group', None],
'detail2_value': ['A', 'anotherplace', 'B', None],
'detail3': ['Hometown', None, None, None],
'detail3_value': ['beautifulplace', None, None, None]})
您可以熔化数据框两次 - 一次用于变量,一次用于它们的值。然后使用 Name 和这个变量来自哪个细节将它们合并回来。合并后的数据框应准备好进行旋转,请参见下面的示例:
id_cols = ['Name']
var_cols = ['detail1','detail2','detail3']
val_cols = ['detail1_value','detail2_value','detail3_value']
val_var_mapping = {k:v for k,v in zip(val_cols, var_cols)}
# extract variables
variables = dataset[id_cols+var_cols].melt(id_vars=['Name'],
value_name='variable',var_name='detail')
# print(variables.head())
# Name detail variable
# 0 Albert detail1 Age
# 1 Bea detail1 Age
# 2 Celine detail1 Age
# 3 Dave detail1 Group
# 4 Albert detail2 Group
# extract values
values = dataset[id_cols+val_cols].melt(id_vars=['Name'], var_name='detail')
values['detail'] = values['detail'].replace(val_var_mapping)
# print(values.head())
# Name detail value
# 0 Albert detail1 30
# 1 Bea detail1 28
# 2 Celine detail1 45
# 3 Dave detail1 A
# 4 Albert detail2 A
# merge and pivot
res = (variables.dropna()
.merge(values, on=id_cols+['detail'])
.pivot(index='Name',columns='variable',values='value')
)
# print(res)
# variable Age Group Hometown
# Name
# Albert 30 A beautifulplace
# Bea 28 None anotherplace
# Celine 45 B None
# Dave None A None
至于 Hometown 与 Hometowns,您可以检查 variable
列的唯一值,并可能用标准化版本替换其中一些值。
#get columns names dynamically
a = dataset.columns[dataset.columns.str.endswith('_value')]
b = dataset.columns[dataset.columns.str.startswith('detail')].difference(a)
df = pd.lreshape(dataset, {'detail':b, 'value':a})
print (df)
Name value detail
0 Albert 30 Age
1 Bea 28 Age
2 Celine 45 Age
3 Dave A Group
4 Albert A Group
5 Bea anotherplace Hometown
6 Celine B Group
7 Albert beautifulplace Hometown
df = df.pivot(index='Name', columns='detail', values='value')
print (df)
detail Age Group Hometown
Name
Albert 30 A beautifulplace
Bea 28 None anotherplace
Celine 45 B None
Dave None A None
最后清理一些数据:
df = df.reset_index().rename_axis(None, axis=1)
print (df)
Name Age Group Hometown
0 Albert 30 A beautifulplace
1 Bea 28 None anotherplace
2 Celine 45 B None
3 Dave None A None
我不确定是否以及如何进行以下转换:
我有一个如下所示的 DataFrame:
Index Name detail1 detail1_value detail2 detail2_value detail3 detail3_value
1 Albert Age 30 Group A Hometown beautifulplace
2 Bea Age 28 Hometown anotherplace None None
3 Celin Age 45 Group B None None
4 Dave Group A None None None None
不过如你所想,我的目标是:
Index Name Age Group Hometown
1 Albert 30 A beautifulplace
2 Bea 28 anotherplace
3 Celin 45 B
4 Dave A
我很确定每个细节只出现一次。 为了让事情变得复杂:我不确定每个细节是否完全相同(在某些情况下,例如 Hometowns 而不是 Hometown)。
到目前为止我能看到的唯一解决方案是从每对列中生成单个数据透视表(如 detail1 和 detail1_value)。在第二步中,创建一个新数据集,并在例如年龄信息中搜索每个数据透视表。 但是我对 python 的信任告诉我,一定有更好的方法...
谢谢!
PS: 可能有帮助:
dataset = pd.DataFrame({'Name': ['Albert', 'Bea', 'Celine', 'Dave'],
'detail1': ['Age', 'Age', 'Age', 'Group'],
'detail1_value': ['30', '28', '45', 'A'],
'detail2': ['Group', 'Hometown', 'Group', None],
'detail2_value': ['A', 'anotherplace', 'B', None],
'detail3': ['Hometown', None, None, None],
'detail3_value': ['beautifulplace', None, None, None]})
您可以熔化数据框两次 - 一次用于变量,一次用于它们的值。然后使用 Name 和这个变量来自哪个细节将它们合并回来。合并后的数据框应准备好进行旋转,请参见下面的示例:
id_cols = ['Name']
var_cols = ['detail1','detail2','detail3']
val_cols = ['detail1_value','detail2_value','detail3_value']
val_var_mapping = {k:v for k,v in zip(val_cols, var_cols)}
# extract variables
variables = dataset[id_cols+var_cols].melt(id_vars=['Name'],
value_name='variable',var_name='detail')
# print(variables.head())
# Name detail variable
# 0 Albert detail1 Age
# 1 Bea detail1 Age
# 2 Celine detail1 Age
# 3 Dave detail1 Group
# 4 Albert detail2 Group
# extract values
values = dataset[id_cols+val_cols].melt(id_vars=['Name'], var_name='detail')
values['detail'] = values['detail'].replace(val_var_mapping)
# print(values.head())
# Name detail value
# 0 Albert detail1 30
# 1 Bea detail1 28
# 2 Celine detail1 45
# 3 Dave detail1 A
# 4 Albert detail2 A
# merge and pivot
res = (variables.dropna()
.merge(values, on=id_cols+['detail'])
.pivot(index='Name',columns='variable',values='value')
)
# print(res)
# variable Age Group Hometown
# Name
# Albert 30 A beautifulplace
# Bea 28 None anotherplace
# Celine 45 B None
# Dave None A None
至于 Hometown 与 Hometowns,您可以检查 variable
列的唯一值,并可能用标准化版本替换其中一些值。
#get columns names dynamically
a = dataset.columns[dataset.columns.str.endswith('_value')]
b = dataset.columns[dataset.columns.str.startswith('detail')].difference(a)
df = pd.lreshape(dataset, {'detail':b, 'value':a})
print (df)
Name value detail
0 Albert 30 Age
1 Bea 28 Age
2 Celine 45 Age
3 Dave A Group
4 Albert A Group
5 Bea anotherplace Hometown
6 Celine B Group
7 Albert beautifulplace Hometown
df = df.pivot(index='Name', columns='detail', values='value')
print (df)
detail Age Group Hometown
Name
Albert 30 A beautifulplace
Bea 28 None anotherplace
Celine 45 B None
Dave None A None
最后清理一些数据:
df = df.reset_index().rename_axis(None, axis=1)
print (df)
Name Age Group Hometown
0 Albert 30 A beautifulplace
1 Bea 28 None anotherplace
2 Celine 45 B None
3 Dave None A None