在Pandas数据帧中水平填充单元格值

时间:2017-08-13 15:49:01

标签: python pandas dataframe reshape linear-interpolation

我知道bfill和ffill填充同一列的行中的值。但是,当您需要在数据框中的某些多列中填充值时,如何执行此操作?

以下是示例:

初始df:

import pandas as pd
inidf = [('Prod', ['P1', 'P2']),
 ('A', ['1', '1']),
 ('1', ['', '40']),
 ('2', ['10', '60']),
 ('3', ['30', '']),
 ('B', ['1', '2']),             
 ]
df = pd.DataFrame.from_items(inidf)
df

  Prod  A   1   2   3  B
0   P1  1      10  30  1
1   P2  1  40  60      2

目标df:

tgtdf = [('Prod', ['P1', 'P2']),
 ('A', ['1', '1']),
 ('1', ['10', '40']),
 ('2', ['10', '60']),
 ('3', ['30', '60']),
 ('B', ['1', '2']),             
 ]
df2 = pd.DataFrame.from_items(tgtdf)
df2

  Prod  A   1   2   3  B
0   P1  1  10  10  30  1
1   P2  1  40  60  60  2

在上面的示例中,要定位的列是名为1,2和3的列。在第一行中,第一个目标列(名为1)具有缺失值,并在此情况下从下一个填充的列复制(命名为2)。在第二行中,最后一个目标列(名为3)具有缺失值,并在此情况下从先前填充的列中复制(名为2)。

3 个答案:

答案 0 :(得分:3)

您可以先使用replace将空格转换为NaN s。

然后选择bfill的行和ffill替换为axis=1的行替换为行:

df = df.replace('', np.nan)
bfill_rows = [0] #if necessary specify more values of index
ffill_rows = [1] #if necessary specify more values of index

df.loc[bfill_rows] = df.loc[bfill_rows].bfill(axis=1)
df.loc[ffill_rows] = df.loc[ffill_rows].ffill(axis=1)
print (df)
  Prod  A   1   2   3  B
0   P1  1  10  10  30  1
1   P2  1  40  60  60  2

如有必要,还可以指定列:

df = df.replace('', np.nan)
cols = ['1','2','3']
bfill_rows = [0]
ffill_rows = [1]

df.loc[bfill_rows, cols] = df.loc[bfill_rows, cols].bfill(axis=1)
df.loc[ffill_rows, cols] = df.loc[ffill_rows, cols].ffill(axis=1)
print (df)

  Prod  A   1   2   3  B
0   P1  1  10  10  30  1
1   P2  1  40  60  60  2

答案 1 :(得分:2)

将所有空格替换为NaNffill,然后bfill替换axis=1'1','2','3'

In [31]: df[['1','2','3']] = df[['1','2','3']].replace('', np.nan).ffill(1).bfill(1)

In [32]: df
Out[32]:
  Prod  A   1   2   3  B
0   P1  1  10  10  30  1
1   P2  1  40  60  60  2

答案 2 :(得分:1)

首先,用NaN值替换空引号。然后根据需要填写或填充,指定axis=0。选择给定行时,轴为0,因为这种选择的结果是一系列。如果要选择多行(例如整个数据帧),则轴将为1

df = df.replace('', np.nan)
df.iloc[0, :].bfill(axis=0, inplace=True)  # Backfill first row.
df.iloc[1, :].ffill(axis=0, inplace=True)  # Forwardfill second row.

>>> df
  Prod  A   1   2   3  B
0   P1  1  10  10  30  1
1   P2  1  40  60  60  2