如何从数据框中提取不同的 4 行组并取消堆叠列

How to extract different groups of 4 rows from dataframe and unstack the columns

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

我想我需要遍历数据帧行并过滤每个 ID 取消堆叠 行到一个新的数据帧中。我无法从 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?

所以基本上您是在进行“部分转置”。这是你想要的吗(引用自)?

示例数据

每行行数不等

  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()