鉴于以下数据框定义,
data = pd.DataFrame({"sec":["dim1", "dim2", "dim3"], # Construct a pandas DataFrame
"m1vc_15":[1,2,3],
"m1vu_15":[10,11,12],
"m2vc_15":[20,21,22],
"m2vu_15":[30,31,32],
"m1vc_16":[4,5,6],
"m1vu_16":[13,14,15],
"m2vc_16":[23,24,25],
"m2vu_16":[33,34,35]})
生成此表结构:
sec m1vc_15 m1vu_15 m2vc_15 m2vu_15 m1vc_16 m1vu_16 m2vc_16 m2vu_16
dim1 1 10 20 30 4 13 23 33
dim2 2 11 21 31 5 14 24 34
dim3 3 12 22 32 6 15 25 35
是否有任何函数或包可以让我创建这个预期的结果?
data2 = pd.DataFrame({"sec":np.repeat(["dim1", "dim2", "dim3", "dim1", "dim2", "dim3"],2), # Construct a pandas DataFrame
"type":np.repeat(['vc','vu'],6),
"year":["2015", "2016", "2015", "2016", "2015", "2016",
"2015", "2016", "2015", "2016", "2015", "2016"],
"m1":[1, 4, 2, 5, 3, 6, 10, 13, 11, 14, 12, 15],
"m2":[20, 23, 21, 24, 22, 25, 30, 33, 31, 34, 32, 35]})
"""
# Output
sec type year m1 m2
dim1 vc 2015 1 20
dim1 vc 2016 4 23
dim2 vc 2015 2 21
dim2 vc 2016 5 24
dim3 vc 2015 3 22
dim3 vc 2016 6 25
dim1 vu 2015 10 30
dim1 vu 2016 13 33
dim2 vu 2015 11 31
dim2 vu 2016 14 34
dim3 vu 2015 12 32
dim3 vu 2016 15 35
"""
转置的逻辑是:
- 包含指标的列名称始终以模式
_integer
结尾。整数是年份的最后两位数字。 - 指标的年份需要转换为新列。
- 数据来源有2年多了,但逻辑是一样的。
- 列名称中的年份之前始终有字符串
vu_
或vc_
。该字符串区分不同类型的对象。数据源中的类型不会有其他值。 - 该字符串需要转置为新列。
- 删除类型和年份后,列名称的其余部分就是最终的指标名称。
- 数据源包含的指标比本示例中的指标多。
最佳答案
您可以使用 wide_to_long
并执行几个步骤来清理列:
df = pd.wide_to_long(data, stubnames=['m1', 'm2'], i=['sec'], j='type_year', suffix='\w+').reset_index()
df[['type', 'year']] = df.type_year.str.split('_', expand=True)
df.year = '20' + df.year
df.drop('type_year', axis=1, inplace=True)
df
sec m1 m2 type year
0 dim1 1 20 vc 2015
1 dim2 2 21 vc 2015
2 dim3 3 22 vc 2015
3 dim1 10 30 vu 2015
4 dim2 11 31 vu 2015
5 dim3 12 32 vu 2015
6 dim1 4 23 vc 2016
7 dim2 5 24 vc 2016
8 dim3 6 25 vc 2016
9 dim1 13 33 vu 2016
10 dim2 14 34 vu 2016
11 dim3 15 35 vu 2016
关于Python- Pandas : create new columns and transpose depending on column names,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73683075/