我有一个从PDF文件中提取的文本构建的熊猫数据帧。 它看起来像这样:
index date description1 description2 value1 value2
0 18-01-2019 some more 1 2
1 NaN text text NaN NaN
2 NaN here NaN NaN NaN
3 19-01-2019 some some 3 4
4 NaN text more NaN NaN
5 NaN here text NaN NaN
6 NaN NaN here NaN NaN
.
.
.
始终至少有 1 行没有 NaN,该行将始终包含日期和值。只有描述位于多行上。
有没有办法根据日期连接行,行低调直到值不是 NaN,并连接描述?
预期产出:
index date description1 description2 value1 value2
0 18-01-2019 some text here more text 1 2
1 19-01-2019 some text here some more text here 3 4
.
.
.
一个想法是通过正向填充date
(或一些用于区分组的任何列(创建用于分组的列,然后如果数字获取第一个值,否则使用join
删除缺失值:
f = lambda x: x.iloc[0] if np.issubdtype(x.dtype, np.number) else ' '.join(x.dropna())
或者在字典中指定每一列:
f1 = lambda x: ' '.join(x.dropna())
f = {'date':'first', 'description1':f1, 'description1':f1, 'value1':'first', 'value2':'first'}
应该动态创建的内容会创建两个字典并合并在一起:
f1 = lambda x: ' '.join(x.dropna())
c =['description1','description2']
d1 = dict.fromkeys(c, f1)
d2 = dict.fromkeys(df.columns.difference(c), 'first')
f = {**d1, **d2}
df = df.groupby(df['date'].ffill()).agg(f).reset_index(drop=True)
#alternative
#df = df.groupby(df['date'].ffill(), as_index=False).agg(f)
print (df)
date description1 description2 value1 value2
0 18-01-2019 some text here more text 1.0 2.0
1 19-01-2019 some text here some more text here 3.0 4.0
将 fillna 与 ffill 一起使用,然后按此时间戳分组,然后使用 agg 中的描述进行操作:
df['date'] = df['date'].fillna(method='ffill')
df_new = df.groupby('date').agg({'description1': lambda x: ' '.join(x.values)})
更新:对于您的输出格式,您可能需要稍微操作索引,如下所示:
df_new = df.groupby('date', as_index=False).agg({'description1': lambda x: ' '.join(x.values)}).reset_index(drop=True)