【问题标题】:How to extract different groups of 4 rows from dataframe and unstack the columns如何从数据框中提取不同的 4 行组并取消堆叠列
【发布时间】:2021-06-02 13:21:55
【问题描述】:

我是 Python 新手,在解决这个问题的过程中迷失了方向:我有一个数据框,其中我需要的信息主要分为 2,3 和 4 行的层。每个组在其中一列中具有不同的 ID。我需要创建另一个数据框,其中行组现在是单行,其中信息 unstacked 在更多列中。稍后我可以删除不需要/冗余的列。

我想我需要遍历数据帧行并过滤每个 ID unstacking 行到一个新的数据帧中。我无法从 unstackgroupby 函数中获得太多。有没有简单的功能或组合可以完成这项任务?

这是数据框的示例:

2_SH1_G8_D_total;Positions tolerance d [z] ;"";0.000; ;0.060;"";0.032;0.032;53%
12_SH1_G8_D_total;Positions tolerance d [z] ;"";-58.000;"";"";"";---;"";""
12_SH1_G8_D_total;Positions tolerance d [z] ;"";-1324.500;"";"";"";---;"";""
12_SH1_G8_D_total;Positions tolerance d [z] ;"";391.000;"";"";"";390.990;"";""
13_SH1_G8_D_total;Flatness;"";0.000; ;0.020;"";0.004;0.004;20%
14_SH1_G8_D_total;Parallelism tolerance  ;"";0.000; ;0.030;"";0.025;0.025;84%
15_SH1_B1_B;Positions tolerance d [x y] ;"";0.000; ;0.200;"";0.022;0.022;11%
15_SH1_B1_B;Positions tolerance d [x y] ;"";265.000;"";"";"";264.993;"";""
15_SH1_B1_B;Positions tolerance d [x y] ;"";1502.800;"";"";"";1502.792;"";""
15_SH1_B1_B;Positions tolerance d [x y] ;"";-391.000;"";"";"";---;"";""

原始数据框包含 4 行信息,但并非总是如此。每个 Id 出现的结束数据框应该只有一行,所有信息都在列中。

到目前为止,在帮助下,我设法运行了这段代码:

with open(path, newline='') as datafile:
    data = csv.reader(datafile, delimiter=';')
    for row in data:
        tmp.append(row)

# Create data table joining data with the same GAT value, GAT is the ID I need
Data = []
Data.append(tmp[0])
GAT = tmp[0][0]
j = 0
counter = 0
for i in range(0,len(tmp)):
    if tmp[i][0] == GAT:
        counter = counter + 1
        if counter == 2:
            temp=(tmp[i][5],tmp[i][7],tmp[i][8],tmp[i][9])
            
            
        else:
            temp = (tmp[i][3], tmp[i][7])

        Data[j].extend(temp)
            
    else:
        Data.append(tmp[i])
        GAT = tmp[i][0]
        j = j + 1

# for i in range(0,len(Data)):
#   print(Data[i])

with open('output.csv', 'w', newline='') as outputfile:
    writedata = csv.writer(outputfile, delimiter=';')
    for i in range(0, len(Data)):
        writedata.writerow(Data[i]);

但并没有真正使用 pandas,这可能会给我更多的数据处理能力。另外,这个open()命令对非ascii字符有问题,我无法解决。

有没有更优雅的方式使用 pandas?

【问题讨论】:

    标签: pandas dataframe loops stack


    【解决方案1】:

    所以基本上你正在做一个“部分转置”。这是你想要的吗(引用自this answer)?

    样本数据

    每行的行数不等

      ID  col1  col2
    0  A   1.0   2.0
    1  A   3.0   4.0
    2  B   5.0   NaN
    3  B   7.0   8.0
    4  B   9.0  10.0
    5  B   NaN  12.0
    

    代码

    import pandas as pd
    import io
    
    # read df
    df = pd.read_csv(io.StringIO("""
    ID   col1    col2
    A      1      2
    A      3      4
    B      5      nan
    B      7      8
    B      9      10
    B      nan    12
    """), sep=r"\s{2,}", engine="python")
    
    # solution
    g = df.groupby('ID').cumcount()
    df = df.set_index(['ID', g]).unstack().sort_index(level=1, axis=1)
    df.columns = [f'{a}_{b+1}' for a, b in df.columns]
    

    结果

    print(df)
    
        col1_1  col2_1  col1_2  col2_2  col1_3  col2_3  col1_4  col2_4
    ID                                                                
    A      1.0     2.0     3.0     4.0     NaN     NaN     NaN     NaN
    B      5.0     NaN     7.0     8.0     9.0    10.0     NaN    12.0
    

    说明

    .set_index(["ID", g]) 步骤之后,数据集变为

          col1  col2
    ID              
    A  0   1.0   2.0
       1   3.0   4.0
    B  0   5.0   NaN
       1   7.0   8.0
       2   9.0  10.0
       3   NaN  12.0
    

    多索引非常适合df.unstack()

    【讨论】:

    • 确实效果很好,比尔!我只需要删除空的和多余的列,做一些重新排列它们,并使用最少的代码完美地完成工作!谢谢!
    猜你喜欢
    • 1970-01-01
    • 2023-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多