jjv*_*ade 5 python transform apply pandas
我有一个DataFrame,其中多索引作为列.我想按级别1进行分组并应用生成新列的函数.我希望将此计算列添加到每个组,因此我的数据框将为每个组添加新列.
我做了一个小的虚拟脚本和函数来复制我想做的事情.
import pandas as pd
import numpy as np
columns = [('A','julian'),('A','geoffrey'),
('B','julian'),('B','geoffrey'),
('C','julian'),('C','geoffrey')]
columns = pd.MultiIndex.from_tuples(columns)
dataframe = pd.DataFrame(data=np.random.rand(10,6),columns=columns)
def addColumn(inputDF):
group = inputDF.columns[0][1]
inputDF['sum', group] = inputDF.sum(axis=1)
return inputDF
newColumnsDataframe = dataframe.groupby(level=1, axis=1).apply(addColumn)
Run Code Online (Sandbox Code Playgroud)
原始数据框如下所示:
A B C
julian geoffrey julian geoffrey julian geoffrey
0 0.204082 0.073676 0.795725 0.279702 0.258185 0.258112
1 0.263235 0.096733 0.507324 0.541198 0.525919 0.757652
2 0.196243 0.028613 0.653408 0.364365 0.174911 0.924733
3 0.528785 0.831569 0.654160 0.738029 0.940831 0.294473
4 0.853517 0.263250 0.803087 0.855270 0.701937 0.264698
5 0.239797 0.069519 0.943544 0.374411 0.189361 0.846647
6 0.980734 0.290414 0.850097 0.873785 0.903645 0.118713
7 0.591942 0.088387 0.566298 0.062140 0.568482 0.872064
8 0.818167 0.061483 0.282050 0.008404 0.449198 0.658370
9 0.217424 0.427602 0.471933 0.171458 0.390549 0.234426
Run Code Online (Sandbox Code Playgroud)
生成的数据框应如下所示(我分别构造了和DataFrame并连接了两个数据帧以实现此结果):
A B C sum A B C \
geoffrey geoffrey geoffrey geoffrey julian julian julian
0 0.073676 0.279702 0.258112 0.611491 0.204082 0.795725 0.258185
1 0.096733 0.541198 0.757652 1.395584 0.263235 0.507324 0.525919
2 0.028613 0.364365 0.924733 1.317710 0.196243 0.653408 0.174911
3 0.831569 0.738029 0.294473 1.864071 0.528785 0.654160 0.940831
4 0.263250 0.855270 0.264698 1.383219 0.853517 0.803087 0.701937
5 0.069519 0.374411 0.846647 1.290578 0.239797 0.943544 0.189361
6 0.290414 0.873785 0.118713 1.282912 0.980734 0.850097 0.903645
7 0.088387 0.062140 0.872064 1.022590 0.591942 0.566298 0.568482
8 0.061483 0.008404 0.658370 0.728257 0.818167 0.282050 0.449198
9 0.427602 0.171458 0.234426 0.833486 0.217424 0.471933 0.390549
sum
julian
0 1.257992
1 1.296478
2 1.024561
3 2.123776
4 2.358542
5 1.372703
6 2.734476
7 1.726721
8 1.549415
9 1.079906
Run Code Online (Sandbox Code Playgroud)
上面脚本中的方法基于对我有意义的内容以及其他人在网上撰写的关于做这类事情的内容.但是,newColumnsDataframe仍然只有6列,而不是8列(每个名称都添加一列).
我注意到当我按level = 0(因此通过A,B或C)进行分组并使用transform时(但是当我在此级别上使用apply时不是这样),newColumnsDataframe确实有9列,每列添加一个sum列.请参阅以下代码:
import pandas as pd
import numpy as np
columns = [('A','julian'),('A','geoffrey'),
('B','julian'),('B','geoffrey'),
('C','julian'),('C','geoffrey')]
columns = pd.MultiIndex.from_tuples(columns)
dataframe = pd.DataFrame(data=np.random.rand(10,6),columns=columns)
def addColumn(inputDF):
group = inputDF.columns[0][1]
inputDF[group, 'sum'] = inputDF.sum(axis=1)
return inputDF
newColumnsDataframe = dataframe.groupby(level=0, axis=1).transform(addColumn)
Run Code Online (Sandbox Code Playgroud)
总是我的理解是,变换在组内的每个列上工作,而apply作为整个数据帧在组上运行.这似乎与此相矛盾.我也注意到,当我按level = 1进行分组并使用transform而不是apply时,会抛出以下错误:
ValueError: Length mismatch: Expected axis has 10 elements, new values have 6 elements
Run Code Online (Sandbox Code Playgroud)
我对发生的事情感到非常困惑.当我在level = 0上使用transform和group时,有没有人知道为什么这个可以工作.为什么在我执行相同但在level = 1上的组时出现错误.为什么在EITHER级别上分组并应用该函数不会在我的最终数据帧中添加列?提前致谢!
(PS:这不是我用来添加列的实际DataFrame或函数,只是一个更简单的插图)
有点乱,但是一句话:
(df.join(pd.concat({'sum': df.groupby(level=1, axis=1).sum()}, axis=1))
.sortlevel(level=1, axis=1))
Run Code Online (Sandbox Code Playgroud)
为我产生这个:
A B C sum A B C \
geoffrey geoffrey geoffrey geoffrey julian julian julian
0 0.073676 0.279702 0.258112 0.611490 0.204082 0.795725 0.258185
1 0.096733 0.541198 0.757652 1.395583 0.263235 0.507324 0.525919
2 0.028613 0.364365 0.924733 1.317711 0.196243 0.653408 0.174911
3 0.831569 0.738029 0.294473 1.864071 0.528785 0.654160 0.940831
4 0.263250 0.855270 0.264698 1.383218 0.853517 0.803087 0.701937
5 0.069519 0.374411 0.846647 1.290577 0.239797 0.943544 0.189361
6 0.290414 0.873785 0.118713 1.282912 0.980734 0.850097 0.903645
7 0.088387 0.062140 0.872064 1.022591 0.591942 0.566298 0.568482
8 0.061483 0.008404 0.658370 0.728257 0.818167 0.282050 0.449198
9 0.427602 0.171458 0.234426 0.833486 0.217424 0.471933 0.390549
sum
julian
0 1.257992
1 1.296478
2 1.024562
3 2.123776
4 2.358541
5 1.372702
6 2.734476
7 1.726722
8 1.549415
9 1.079906
Run Code Online (Sandbox Code Playgroud)
我只是说“这是我的df,让我们首先按人员姓名进行分组并求和,然后将这两个求和列连接回原始值df,然后使用和sortlevel进行排序。”level=1axis=1
因此,“sum”出现在“ Ccolumn”之后的唯一原因只是因为字母s出现在“column”之后C。如果您有一个名为 的列x,则这将不起作用。但不确定这是否重要。
这是df我用于娱乐目的的:
df = pd.DataFrame({
('C', 'julian'): [0.258185, 0.52591899999999991, 0.17491099999999998, 0.94083099999999997, 0.70193700000000003, 0.189361, 0.90364500000000003, 0.56848199999999993, 0.44919799999999993, 0.39054899999999998],
('B', 'geoffrey'): [0.27970200000000001, 0.54119799999999996, 0.36436499999999999, 0.73802900000000005, 0.85527000000000009, 0.37441099999999999, 0.87378500000000003, 0.062140000000000001, 0.008404, 0.171458],
('A', 'julian'): [0.20408199999999999, 0.263235, 0.196243, 0.52878500000000006, 0.85351699999999997, 0.23979699999999998, 0.98073399999999999, 0.59194199999999997, 0.81816699999999998, 0.21742399999999998],
('B', 'julian'): [0.79572500000000002, 0.507324, 0.65340799999999999, 0.65416000000000007, 0.803087, 0.94354400000000005, 0.85009699999999988, 0.56629799999999997, 0.28205000000000002, 0.47193299999999999],
('A', 'geoffrey'): [0.073676000000000005, 0.096733, 0.028613, 0.831569, 0.26324999999999998, 0.069519000000000011, 0.29041400000000001, 0.088387000000000007, 0.061483000000000003, 0.42760200000000004],
('C', 'geoffrey'): [0.25811200000000001, 0.75765199999999999, 0.92473300000000003, 0.29447299999999998, 0.26469799999999999, 0.84664699999999993, 0.11871300000000001, 0.87206399999999995, 0.65837000000000001, 0.23442600000000002]},
columns=pd.MultiIndex.from_tuples([('A','julian'),('A','geoffrey'), ('B','julian'),('B','geoffrey'), ('C','julian'),('C','geoffrey')]))
Run Code Online (Sandbox Code Playgroud)
编辑:
这是另一种方法:
sum_columns = [('sum', name) for name in df.columns.levels[1].tolist()]
df[sum_columns] = df.groupby(axis=1, level=1).sum()
df = df.sortlevel(level=1, axis=1)
Run Code Online (Sandbox Code Playgroud)
sum_columns- 看起来像这样[('sum', 'geoffrey'), ('sum', 'julian')]。
df[sum_columns]为第 1 层的每个名称创建一个新的“sum”列。
如果希望名称旁边有总和列,请使用sortlevel。
| 归档时间: |
|
| 查看次数: |
1310 次 |
| 最近记录: |