在 Pandas 数据框中水平填充单元格值
Filling cell values horizontally in Pandas dataframe
我知道 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)中复制的。
首先,用 NaN 值替换空引号。然后根据需要进行 ffill 或 bfill,指定 axis=0
。当 select 给定行时,轴是 0
,因为这样的 selection 的结果是一个系列。如果你要 select 多行(例如整个数据框),那么轴将是 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
您可以先使用 replace
将空格转换为 NaN
s。
然后 select 行 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
将所有空格替换为 NaN
s,首先是 ffill
,然后是 axis=1
上的 bfill
,用于列 '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
我知道 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)中复制的。
首先,用 NaN 值替换空引号。然后根据需要进行 ffill 或 bfill,指定 axis=0
。当 select 给定行时,轴是 0
,因为这样的 selection 的结果是一个系列。如果你要 select 多行(例如整个数据框),那么轴将是 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
您可以先使用 replace
将空格转换为 NaN
s。
然后 select 行 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
将所有空格替换为 NaN
s,首先是 ffill
,然后是 axis=1
上的 bfill
,用于列 '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