2015-01-16 4 views
5

У меня есть pandas dataframe df с pandas.tseries.index.DatetimeIndex как индекс.Pandas заменяет значения в таймсерах dataframe

данные, как это:

Time     Open High Low Close Volume 
2007-04-01 21:02:00 1.968 2.389 1.968 2.389 18.300000 
2007-04-01 21:03:00 157.140 157.140 157.140 157.140 2.400000 

....

Я хочу, чтобы заменить один Datapoint, позволяет день 2,389 в колонке Закрыть с NaN:

In: df["Close"].replace(2.389, np.nan) 
Out: 2007-04-01 21:02:00  2.389 
    2007-04-01 21:03:00 157.140 

Заменить сделал не изменяйте 2.389 до NaN. Что не так?

ответ

6

replace не может работать с поплавками, так как с плавающей точкой представление вы видите в repr в DataFrame не может быть такой же, как основной поплавок. Например, фактическое Close значение может быть:

In [141]: df = pd.DataFrame({'Close': [2.389000000001]}) 

все же магнезии из df выглядит следующим образом:

In [142]: df 
Out[142]: 
    Close 
0 2.389 

Так вместо проверки флоат равенства, как правило, лучше, чтобы проверить близость:

In [150]: import numpy as np 
In [151]: mask = np.isclose(df['Close'], 2.389) 

In [152]: mask 
Out[152]: array([ True], dtype=bool) 

Вы можете использовать булеву маску, чтобы выбрать и изменить нужные значения:

In [145]: df.loc[mask, 'Close'] = np.nan 

In [146]: df 
Out[146]: 
    Close 
0 NaN 
+0

Это сработало! Я немного смущен, хотя в исходном csv это точно 2,389 - почему значение изменилось после загрузки его в dataframe? Все, что я сделал, было импортировано следующим образом: 'df = read_csv (" data.csv ", parse_dates = [0], infer_datetime_format = True, index_col = 0)' – harbun

+0

[Репликация с плавающей запятой десятичных знаков не является точной] (http://docs.python.org/tutorial/floatingpoint.html#representation-error). Поэтому, когда строка CSV «2.389» анализируется в поплавок, плавающее значение не равно 2.389; это вместо числа, ближайшего к 2.389, которое представляется в виде поплавка. [Чтобы увидеть точное значение] (https://docs.python.org/2/tutorial/floatingpoint.html#floating-point-arithmetic-issues-andlimitations), хранящиеся в поплате Python, используйте 'Decimal'. Например, 'import decimal',' decimal.Decimal (2.389) 'дает' Decimal ('2.388999999999999790389892950770445168018341064453125') ' – unutbu

+0

Также обратите внимание, что DataFrame хранит float в массиве NumPy dtype float32 или float64 - 32-разрядный или 64-битного поплавка. На моей (64-битной) машине 'pd.DataFrame ([[2.389]]). Iloc [0,0]' возвращает '2.3889999999999998'. – unutbu

2

Вы должны присвоить результат df['Close'] или передать из параметров inplace=True: df['Close'].replace(2.389, np.NaN, inplace=True)

т.д .:

In [5]: 

df['Close'] = df['Close'].replace(2.389, np.NaN) 
df['Close'] 
Out[5]: 
0  2.389 
1 157.140 
Name: Close, dtype: float64 

Большинство операций панды возвращает копию, а некоторые принимают параметров inplace.

Проверьте документы: http://pandas.pydata.org/pandas-docs/stable/generated/pandas.Series.replace.html#pandas.Series.replace

+0

К сожалению, в этом случае это не сработало, но если бы замена действительно находила значение, это был бы путь. – harbun

+0

Я думаю, что ответ unutbu - это очевидный правильный ответ, странно для меня он отлично работал, не делая ничего особенного. – EdChum

Смежные вопросы