我有一个pandas数据帧df
为
Date cost NC
20 5 NaN
21 7 NaN
23 9 78.0
25 6 80.0
现在我需要做的是填充缺少的日期,因此只有在前一行中有数字时才用x
值填充列。那就是我希望输出像
Date cost NC
20 5 NaN
21 7 NaN
22 x NaN
23 9 78.0
24 x x
25 6 80.0
请参阅日期22缺失且21 NC
缺失,因此22 cost
分配给x,但NC
已分配给NaN
。现在将Date
列设置为index
并将reindex
设置为缺失值,我可以到达此处
Date cost NC
20 5.0 NaN
21 7.0 NaN
22 NaN NaN
23 9.0 78.0
24 NaN NaN
25 6.0 80.0
但是我无法达到最终输出。如果您这样想,就像ffill()
一样,但不必填写前一行,您必须将x
放在此处。
我有另一个问题。在这里,我有一个像这样的数据框df
Date type cost
10 a 30
11 a 30
11 b 25
13 a 27
在这里,我还要填写缺失的值并使其像这样
Date type cost
10 a 30
11 a 30
11 b 25
12 a 30
12 b 25
13 a 27
你可以看到日期11有2个数据行所以都被复制到12个。我为这个问题编写了这个程序
missing=[12]
for i in missing:
new_date=i
i-=1 #go to previous date
k=df[df["Date"] == i].index.tolist()[-1]+1 #index where to be filled
data=pd.DataFrame(df[df["Date"] == i].values,columns=df.columns)
data["Date"]=new_date
df=pd.concat([df.iloc[:k],data,df.iloc[k:]]).reset_index(drop=True)
现在对于大型数据集,上述程序需要花费大量时间,因为每次都需要找到索引和concat 3数据帧。有没有更好更有效的方法来解决这个问题?
答案 0 :(得分:1)
我认为没有办法只填充“中间”值,但这是一种方法(使用ffill
,bfill
和fillna
):< / p>
In [11]: df1 # assuming Date is the index via df.set_index("Date")
Out[11]:
cost NC
Date
20 5 NaN
21 7 NaN
23 9 78.0
25 6 80.0
In [12]: df2 = df1.reindex(np.arange(20,27))
# 26 is sufficient, but let's see it working!
In [13]: df2
Out[13]:
cost NC
Date
20 5.0 NaN
21 7.0 NaN
22 NaN NaN
23 9.0 78.0
24 NaN NaN
25 6.0 80.0
26 NaN NaN
你不想填写“外部”NaN,可以使用:
In [14]: df2.bfill().notnull() & df2.ffill().notnull()
Out[14]:
cost NC
Date
20 True False
21 True False
22 True False
23 True True
24 True True
25 True True
26 False False
现在,我们可以更新这些内容(如果它们将使用fillna
进行更新):
In [15]: df2[df2.bfill().notnull() & df2.ffill().notnull()] = df2.fillna(0) # x = 0
In [16]: df2
Out[15]:
cost NC
Date
20 5.0 NaN
21 7.0 NaN
22 0.0 NaN
23 9.0 78.0
24 0.0 0.0
25 6.0 80.0
26 NaN NaN
要(部分地)回答第二个问题,IMO在这种情况下你最好总是以一个支点开始(这会给你一个更好的起点):
In [21]: df
Out[21]:
Date type cost
0 10 a 30
1 11 a 30
2 11 b 25
3 13 a 27
In [22]: df.pivot_table("cost", "Date", "type")
Out[22]:
type a b
Date
10 30.0 NaN
11 30.0 25.0
13 27.0 NaN
也许你想从那里填补? (并在必要时拆开)。