我有这个DataFrame:
>>> data = [['Ob01',1,2,3],['Ob02',4,5,6],['Ob03',7,8,9]]
>>> dfr = pd.DataFrame(data, columns = ['Name', 'A','B','C'])
dfr
Name A B C
0 Ob01 1 2 3
1 Ob02 4 5 6
2 Ob03 7 8 9
我的问题是我需要对列"中的每个对象进行一些操作;名称";,并且为每个对象添加新的子行。我必须对每个Object做一些运算,例如将"Object"乘以2;A"B"C";属性,并将过去的结果除以3,但我需要在其他行中看到这些操作的结果,比如:
Name Op A B C
0 Ob01 Val 1 2 3
mul2 2 4 6
div3 0.66 1.33 2
1 Ob02 Val 4 5 6
mul2 8 10 12
div3 2.66 3.33 4
2 Ob03 Val 7 8 9
mul2 14 16 18
div3 4.66 5.33 6
或者,如果我为每个对象添加每个操作的列,会更好吗?无论如何,我不知道从哪里开始,我的对象列表太长了,但我想代表我的一些数据作为例子。
melt
+pivot
+stack
选项:
new_df = dfr.reset_index().melt(id_vars=['index', 'Name'], value_name='Val')
new_df['mul2'] = new_df['Val'] * 2
new_df['div3'] = new_df['Val'] / 3
new_df = (
new_df.pivot(index=['index', 'Name'], columns='variable')
.stack(level=0)
.reset_index()
.set_index('index')
.rename(columns={'level_2': 'Op'})
.rename_axis(index=None, columns=None)
)
set_index
+concat
+stack
:
CCD_ 7轴=1,其中CCD_。
然后清理索引和列等:
dfr = dfr.reset_index().set_index(['index', 'Name'])
cols = ['A', 'B', 'C']
mul2 = dfr[cols] * 2
div3 = dfr[cols] / 3
new_df = (
pd.concat(
(dfr, mul2, div3),
axis=1,
keys=('Val', 'mul2', 'div3')
)
.stack(level=0)
.reset_index()
.set_index('index')
.rename(columns={'level_2': 'Op'})
.rename_axis(None)
)
new_df
:
Name Op A B C
0 Ob01 Val 1.000000 2.000000 3.0
0 Ob01 div3 0.333333 0.666667 1.0
0 Ob01 mul2 2.000000 4.000000 6.0
1 Ob02 Val 4.000000 5.000000 6.0
1 Ob02 div3 1.333333 1.666667 2.0
1 Ob02 mul2 8.000000 10.000000 12.0
2 Ob03 Val 7.000000 8.000000 9.0
2 Ob03 div3 2.333333 2.666667 3.0
2 Ob03 mul2 14.000000 16.000000 18.0
使用set_index
和pd.concat
:
df = df.set_index('Name')
df = pd.concat([df.assign(OP = 'Val') , df.mul(2).assign(OP = 'mul2') , df.div(3).assign(OP = 'div3')]).sort_values('Name')
要进一步转换:
df = df.groupby([df.index,'OP']).agg(float)
df = df.convert_dtypes()
输出:
A B C
Name OP
Ob01 Val 1.0 2.0 3
div3 0.333333 0.666667 1
mul2 2.0 4.0 6
Ob02 Val 4.0 5.0 6
div3 1.333333 1.666667 2
mul2 8.0 10.0 12
Ob03 Val 7.0 8.0 9
div3 2.333333 2.666667 3
mul2 14.0 16.0 18