示例数据:
test = structure(list(A = 1:16, B = c(".", NA, NA, NA, ".", NA, NA,
NA, ".", NA, NA, NA, ".", NA, NA, NA), C = c(6L, NA, NA, NA,
6L, NA, NA, NA, 6L, NA, NA, NA, 6L, NA, NA, NA), D = c(58, 59,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13), E = c(0.945252,
0.949158, 0.945252, 0.945252, 0.945252, 0.945252, 0.945252, 0.949158,
0.949158, 0.949158, 0.949158, 0.945252, 0.945252, 0.945252, 0.945252,
0.945252), F = c(62.4375, NA, 62.34375, NA, 62.28125, NA, 62.28125,
NA, 62.25, NA, 62.21875, NA, 62.25, NA, 62.28125, NA)), .Names = c("A",
"B", "C", "D", "E", "F"), row.names = c(NA, 16L), class = "data.frame")
我在R中有上面的数据框。我想用一些逻辑替换NA
值。
在R
我写道:
test2 = test
library(data.table)
for(m in 1:length(test2)){test2[,m] = ifelse(is.na(test2[,m]),
ifelse(is.na(shift(test2[,m]))==F, shift(test2[,m]),
ifelse(is.na(shift(test2[,m], n=2))==F, shift(test2[,m], n=2),
ifelse(is.na(shift(test2[,m], n=3))==F, shift(test2[,m], n=3),
ifelse(is.na(shift(test2[,m], n=4))==F, shift(test2[,m], n=4),
shift(test2[,m], n=5)))))
, test2[,m])}
这实现了我想要的。但是现在,我所做的一切都是从R
转换为Python
。除了这个问题,我已设法翻译我的所有工作。
我写了等价物:
import numpy as np
import pandas as pd
for m in range(0, len(test2.columns)):
if test2.iloc[:,m].isnull():
if test2.iloc[:,m].shift(periods=1).notnull():
test2.iloc[:,m] = test2.iloc[:,m].shift(periods=1)
else:
if test2.iloc[:,m].shift(periods=2).notnull():
test2.iloc[:,m] = test2.iloc[:,m].shift(periods=2)
else:
if test2.iloc[:,m].shift(periods=3).notnull():
test2.iloc[:,m] = test2.iloc[:,m].shift(periods=3)
else:
if test2.iloc[:,m].shift(periods=4).notnull():
test2.iloc[:,m] = test2.iloc[:,m].shift(periods=4)
else:
test2.iloc[:,m] = test2.iloc[:,m].shift(periods=5)
我意识到这在Python
中不起作用甚至没有意义,因为R
在ifelse
使用shift
时会将逻辑应用于每一行,而在Python
我相信我会问这个系列是True
还是False
。为了速度,我真的不想遍历整个数据框,这就是shift
在R
中如此之大的原因。我猜可能有一种简单的方法可以使用If
中的iloc
和Python
,但我{a} Python
noob。
CSV:
A B C D E F
1 . 6 58 0.945252 62.4375
2 59 0.949158
3 0 0.945252 62.34375
4 1 0.945252
5 . 6 2 0.945252 62.28125
6 3 0.945252
7 4 0.945252 62.28125
8 5 0.949158
9 . 6 6 0.949158 62.25
10 7 0.949158
11 8 0.949158 62.21875
12 9 0.945252
13 . 6 10 0.945252 62.25
14 11 0.945252
15 12 0.945252 62.28125
16 13 0.945252
答案 0 :(得分:1)
在python中证明这很容易。一旦你认识到我的问题基本上是一个归责问题,我想用最后的观察结果,我相信它变得如此简单:
test2 = test.fillna(method = 'pad')
在R
中为未来找到了一种更简单的方法
library(zoo)
test2 = na.locf(test)
答案 1 :(得分:1)
您可以使用DataFrame.ffill
,它比调用fillna
稍短。
test = test.ffill()
它的作用是使用每行中第一个后续的非空值向前填充所有NaN
。或者,您可以使用fillna
调用method='ffill'
来执行相同的操作:
test = test.fillna(method='ffill')
与method='pad'
完全相同。