如何使用 Python 将一系列重复的数据行转换为多条记录的列?

我们有来自测量多个部件的设备的数据,并将每个部件的多个测量结果输出到一个 CSV 文件中。我们将 CSV 文件读入具有如下结构的数据帧:


PartNo  12

Meas1   45

Meas2   23

!END

PartNo  13

Meas1   63

Meas2   73

!END

PartNo  12

Meas1   82

Meas2   84

!END

“!END”标志表示一个部分的数据在哪里结束,下一个部分从哪里开始。我们想重塑数据,使其看起来像:


PartNo  Meas1   Meas2

12      45      23

13      63      73

12      82      84

(请注意,一个部分可能出现不止一次 - 因此没有字段保证在所有记录中都是唯一的。)


枢轴产生:


0   !END  Meas1  Meas2  PartNo

0    NaN    NaN    NaN    12.0

1    NaN   45.0    NaN     NaN

2    NaN    NaN   23.0     NaN

3    NaN    NaN    NaN     NaN

4    NaN    NaN    NaN    13.0

5    NaN   63.0    NaN     NaN

6    NaN    NaN   73.0     NaN

7    NaN    NaN    NaN     NaN

8    NaN    NaN    NaN    12.0

9    NaN   82.0    NaN     NaN

10   NaN    NaN   84.0     NaN

11   NaN    NaN    NaN     NaN

我如何压缩这些行以按 PartNo 分组?

转置产生:


       0      1      2     3       4      5      6     7       8      9      10    11

0  PartNo  Meas1  Meas2  !END  PartNo  Meas1  Meas2  !END  PartNo  Meas1  Meas2  !END

1      12     45     23   NaN      13     63     73   NaN      12     82     84   NaN

我怎样才能每第 4 个项目重置该行?


我可以在原始数据框中创建一个新的索引列,然后遍历行,使用 !END 为每一行递增索引(然后使用索引对数据进行分组),但似乎应该有一个更优雅的方法变形函数来处理这种情况,或者可能有一个 Pivot 或 Transpose 的参数可以处理这种情况。我是 Python 初学者。这是完整的代码:


import pandas as pd

from io import StringIO


tdata = (

'PartNo,    12\n'

'Meas1, 45\n'

'Meas2, 23\n'

'!END\n'

'PartNo,    13\n'

'Meas1, 63\n'

'Meas2, 73\n'

'!END\n'

'PartNo,    12\n'

'Meas1, 82\n'

'Meas2, 84\n'

'!END\n')

tdf = pd.read_csv(StringIO(tdata), header=None)

print(tdf)

print(tdf.pivot(index=None, columns=0, values=1))

print(tdf.T)


湖上湖
浏览 237回答 4
4回答

当年话下

#having dataframe x:>>> x = pd.DataFrame([['PartNo',12],['Meas1',45],['Meas2',23],['!END',''],['PartNo',13],['Meas1',63],['Meas2',73],['!END',''],['PartNo',12],['Meas1',82],['Meas2',84],['!END','']])>>> x         0   10   PartNo  121    Meas1  452    Meas2  233     !END    4   PartNo  135    Meas1  636    Meas2  737     !END    8   PartNo  129    Meas1  8210   Meas2  8411    !END    #grouping by first column, and aggregating values to list. First column then contains Series that you want. By converting each list in this series to series, dataframe is created, then you just need to transpose>>> df = x.groupby(0).agg(lambda x: list(x))[1].apply(lambda x: pd.Series(x)).transpose()>>> df[['PartNo','Meas1','Meas2']]0 PartNo Meas1 Meas20     12    45    231     13    63    732     12    82    84

皈依舞

这是我会怎么做。我会将文件解析为任何文本文件,然后根据我需要的字段创建记录。我会使用 '!END' 行作为行创建完成的指示器,将其写入列表,然后最终将列表转换为 DataFrameimport pandas as pdfilename='PartDetail.csv'with open(filename,'r') as file:    LinesFromFile=file.readlines()    RowToWrite=[]for EachLine in LinesFromFile:    ValuePosition=EachLine.find(" ")+1    CurrentAttrib=EachLine[0:ValuePosition-1]    if CurrentAttrib=='PartNo':        PartNo=EachLine[ValuePosition+1:len(EachLine)-1].strip()    if CurrentAttrib=='Meas1':        Meas1=EachLine[ValuePosition+1:len(EachLine)-1].strip()    if CurrentAttrib=='Meas2':        Meas2=EachLine[ValuePosition+1:len(EachLine)-1].strip()    if EachLine[0:4]=='!END':        RowToWrite.append([PartNo,Meas1,Meas2])        PartsDataDF=pd.DataFrame(RowToWrite,columns=['PartNo','Meas1','Meas2']) #Converting to DataFrame这将为您提供一个更清晰的 DataFrame,如下所示:-

GCT1015

该文件不是 csv 文件,因此使用 csv 模块解析它无法产生正确的输出。它不是众所周知的格式,所以我会使用自定义解析器:with open(filename) as fd:    data  = []    row = None    for line in fd:        line = line.strip()        if line == '!END':            row = None        else:            k,v = line.split(None, 1)            if row is None:                row = {k : v}                data.append(row)            else:                row[k] = vheader = set(i for row in data for i in row.keys())df = pd.DataFrame(data, columns=header)

墨色风雨

根据提供的信息,我认为你应该能够使用这种方法实现你想要的:df = df[df[0] != '!END']out = df.groupby(0).agg(list).T.apply(lambda x: x.explode(), axis=0)输出:0 Meas1 Meas2 PartNo1    45    23     121    63    73     131    82    84     12这基本上按 PartNo、Meas1 和 Meas2 键对原始 df 进行分组,并为每个列表创建一个列表。然后将每个列表分解为一个 pd.Series,从而为每个列表创建一个列,行数等于条目数每个键(都应该相同)
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python