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

parsing CSV to pandas dataframes (one-to-many unmunge)

我有一个 csv 文件导入到 pandas 数据框。它可能来自结合了一对多父级和详细信息 table 的数据库导出。 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 等等...)

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

我可以使用:

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

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

我应该制作数据框列表、数据框字典还是数据框面板?

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

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

谢谢。

您可以利用第一个 column 似乎是空的这一事实,除非它是 .fillna(method='ffill') and then .groupby('header1') 的新 sample 记录来获取所有单独的组。在这些上,您可以立即计算统计数据或单独存储 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

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

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