将CSV解析为pandas数据帧(一对多unmunge)

时间:2016-06-14 00:13:58

标签: python csv pandas dataframe panels

我有一个导入到pandas数据帧的csv文件。它可能来自数据库导出,它组合了一对多父级和详细信息表。 csv文件的格式如下:

header1, header2, header3, header4, header5, header6

sample1, property1,,,average1,average2
,,detail1,detail2,,
,,detail1,detail2,,
,,detail1,detail2,,

sample2, ...
,,detail1,detail2,,
,,detail1,detail2,,
...

(即line 0headerline 1record 1lines 2n是详细信息,第n + 1行是记录2等等......)

将详细信息拆分(重新规范化)到可以使用DataFrames记录中的值引用的单独sample#的最佳方法是什么?每个样本的每个细节子集的数量都不同。

我可以使用:

samplelist = df.header2[pd.notnull(df.header2)]

获取每个样本的起始索引,以便我可以将samplelist.index [0]抓取到samplelist.index [1]并将其放在一个较小的数据帧中。细节记录本身没有参考它们来自哪个样本,因此必须从csv文件的顺序推断出来(注意我的例子中没有填充/空字段的交集)。

我应该列出数据帧,数据帧的数据集还是一组数据帧?

我可以以某种方式从sample1记录字段创建变量,并以某种方式将它们附加到只有详细记录的每个数据帧(比如一组具有多个标量成员和每个数据帧的对象)?

最终,我将根据每个详细记录分组创建数据统计数据,并将其与样本记录中的值进行对比(例如样本类型,日期或日期等,以及mystatistic)。我将创建中间系列,也可以附加到样本分组,如核密度估计PDF或直方图。

感谢。

2 个答案:

答案 0 :(得分:0)

您可以使用第一个column似乎为空的事实,除非它是.fillna(method='ffill')的新sample记录,然后是.groupby('header1')以获取所有单独的组。在这些方面,您可以立即计算统计数据或将其存储为单独的DataFrame。高级草图如下:

df.header1 = df.header1.fillna(method='ffill')
for sample, data in df.groupby('header1'):
     print(sample) # access to sample name
     data = ... # process sample records

答案 1 :(得分:0)

上面的答案让我朝着正确的方向前进。通过进一步的工作,使用了以下内容。事实证明,我需要使用两列作为复合键来唯一标识样本。

df.header1 = df.header1.fillna(method='ffill')
df.header2 = df.header2.fillna(method='ffill')

grouped = df.groupby(['header1','header2'])

samplelist = []
dfParent = pd.DataFrame()
dfDetail = pd.DataFrame()

for sample, data in grouped:
    samplelist.append(sample)
    dfParent = dfParent.append(grouped.get_group(sample).head(n=1), ignore_index=True)
    dfDetail = dfDetail.append(data[1:], ignore_index=True)

dfParent = dfParent.drop(['header3','header4',etc...]) # remove columns only used in 
                                                       # detail records
dfDetail = dfDetail.drop(['header5','header6',etc...]) # remove columns only used once
                                                       # per sample

# Now details can be extracted by sample number in the sample list 
# (e.g. the first 10 for sample 0)

samplenumber = 0

dfDetail[
    (dfDetail['header1'] == samplelist[samplenumber][0]) &
    (dfDetail['header2'] == samplelist[samplenumber][1])
    ].header3[:10]

有用的链接是:

Pandas groupby and get_group

Pandas append to DataFrame