我有以下示例:
import pandas as pd
import numpy as np
df = pd.DataFrame([(0,2,5), (2,4,None),(7,-5,4), (1,None,None)])
def clean(series):
start = np.min(list(series.index[pd.isnull(series)]))
end = len(series)
series[start:] = series[start-1]
return series
我的目标是获取一个数据框,其中包含None值的每一行都填入最后一个可用的数值。
所以,例如,在数据帧的第3行运行此函数,我将生成以下内容:
row = df.ix[3]
test = clean(row)
test
0 1.0
1 1.0
2 1.0
Name: 3, dtype: float64
我无法使用.apply()方法工作,即df.apply(clean,axis = 1)
我应该提到这是一个玩具示例 - 我将在真实中编写的自定义函数在填充值时更具动态性 - 所以我不是在寻找像.ffill或.fillna这样的基本实用程序
答案 0 :(得分:1)
apply方法不起作用,因为当行完全填满时,clean
函数将不知道从哪里开始索引,因为给定系列的空数组。
因此在更改系列数据之前使用条件,即
def clean(series):
# Creating a copy for the sake of safety
series = series.copy()
# Alter series if only there exists a None value
if pd.isnull(series).any():
start = np.min(list(series.index[pd.isnull(series)]))
# for completely filled row
# series.index[pd.isnull(series)] will return
# Int64Index([], dtype='int64')
end = len(series)
series[start:] = series[start-1]
return series
df.apply(clean,1)
输出:
0 1 2 0 0.0 2.0 5.0 1 2.0 4.0 4.0 2 7.0 -5.0 4.0 3 1.0 1.0 1.0
希望它澄清为什么申请不起作用。我还建议考虑使用builtins来清理数据,而不是从头开始编写函数。
答案 1 :(得分:0)
首先,这是解决玩具问题的代码。但是这段代码并不是你想要的。
df.ffill(axis=1)
接下来,我尝试测试您的代码。
df.apply(clean,axis=1)
#...start = np.min(list(series.index[pd.isnull(series)]))...
#=>ValueError: ('zero-size array to reduction operation minimum
# which has no identity', 'occurred at index 0')
要了解情况,请使用lambda函数进行测试。
df.apply(lambda series:list(series.index[pd.isnull(series)]),axis=1)
0 []
1 [2]
2 []
3 [1, 2]
dtype: object
下一个表达式会产生相同的值错误:
import numpy as np
np.min([])
总之,pandas.apply()运行良好,但清洁功能并不适用。
答案 2 :(得分:0)
你可以使用像填充物一样的回填物吗?我认为如果回填符合您的情况,这可能会更有效..
即。
df.fillna(method='backfill')
然而,假设细胞中存在np.nan?
https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.fillna.html