如果至少有一个单元格是 NaN,熊猫将行连接起来



我有一个从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)

最新更新