更改熊猫数据框的架构(索引-列)

时间:2020-03-20 13:30:26

标签: python pandas

首先,这是我在StackOverflow中的第一个问题,然后告诉我是否做错了(对不起我的英语,我是法国人:))。

这个问题是在Python脚本中找到更改数据框架构的最佳方法。

这就是我所拥有的(数据帧):

    Name    Point    LoadCase    Data1    Data2    Data3
0   Name1   point1   LC1         1        2        4
1   NA      NA       NA          5        6        7
2   NA      TOTAL    NA          8        9        10
3   Name1   point1   LC2         11       12       13
4   NA      NA       NA          14       15       16
5   NA      TOTAL    NA          17       18       19
6   Name2   point2   LC1         20       21       22      
7   NA      NA       NA          23       24       25
8   NA      TOTAL    NA          26       27       28
9   Name2   point2   LC2         29       30       31
10  NA      NA       NA          32       33       34
11  NA      TOTAL    NA          35       36       37

这就是我想要的(TOTAL行的结果,但具有点ID)

    Name    Point    Data    LC1    LC2
0   Name1   Point1   Data1   8      17
1   Name1   Point1   Data2   9      18
2   Name1   Point1   Data3   10     19
3   Name2   Point2   Data1   26     35
4   Name2   Point2   Data2   27     36
5   Name2   Point2   Data3   28     37

要做到这一点,我尝试了几种方法,但没有一项对我有用(或者我没有设法使它们起作用),我尝试使用stack()函数和dataframe的multiIndex函数。

如果您有任何帮助我的想法,请与我分享。

谢谢!

2 个答案:

答案 0 :(得分:1)

您可以创建一个布尔列来跟踪哪些行是“ TOTAL”行,清理并向前填充“ Point”,然后融化并旋转数据。

import pandas as pd
import numpy as np

df['is_total'] = df.Point.eq('TOTAL')
df['Point'] = df.Point.replace('TOTAL', np.nan)

out = (df.ffill()
         .query('is_total')
         .drop('is_total', axis=1)
         .melt(id_vars=['Name', 'Point', 'LoadCase'], var_name='Data')
         .pivot_table(index=['Name', 'Point', 'Data'], columns='LoadCase')
      )
out.columns = out.columns.get_level_values(-1)
out = out.reset_index()
out
# returns:
LoadCase   Name   Point   Data  LC1  LC2
0         Name1  point1  Data1    8   17
1         Name1  point1  Data2    9   18
2         Name1  point1  Data3   10   19
3         Name2  point2  Data1   26   35
4         Name2  point2  Data2   27   36
5         Name2  point2  Data3   28   37

答案 1 :(得分:0)

也许进行了一些.loc过滤,ffill,然后是meltgroupby,然后是unstack

df.loc[df['Point'].eq('TOTAL'),'var'] = 'Total'
df['Point'] = df['Point'].replace('TOTAL',np.nan).ffill()

df1 = df.ffill().loc[df["var"].eq("Total")].drop("var", axis=1).melt(
    id_vars=["Name", "Point", "LoadCase"]
).groupby(["Name", "Point", "LoadCase", "variable"]).first().unstack("LoadCase").reset_index()

print(df1)

           Name   Point variable value    
LoadCase                           LC1 LC2
0         Name1  point1    Data1     8  17
1         Name1  point1    Data2     9  18
2         Name1  point1    Data3    10  19
3         Name2  point2    Data1    26  35
4         Name2  point2    Data2    27  36
5         Name2  point2    Data3    28  37