2016-08-30 6 views
2

Я использую панд 0.17.0 и имеют df, подобные этот:Есть ли способ предотвратить переход dtype с Int64 на float64 при повторной передаче/повышении дискретизации временного ряда?

df.head() 
Out[339]: 
         A  B C 
DATE_TIME       
2016-10-08 13:57:00 in 5.61 1 
2016-10-08 14:02:00 in 8.05 1 
2016-10-08 14:07:00 in 7.92 0 
2016-10-08 14:12:00 in 7.98 0 
2016-10-08 14:17:00 out 8.18 0 

df.tail() 
Out[340]: 
         A  B C 
DATE_TIME       
2016-11-08 13:42:00 in 8.00 0 
2016-11-08 13:47:00 in 7.99 0 
2016-11-08 13:52:00 out 7.97 0 
2016-11-08 13:57:00 in 8.14 1 
2016-11-08 14:02:00 in 8.16 1 

dtypes со следующим:

print (df.dtypes) 
A  object 
B float64 
C  int64 
dtype: object 

Когда я индексировать мой df в минутные интервалы всех столбцы int64 изменения float64.

index = pd.date_range(df.index[0], df.index[-1], freq="min") 
df2 = df.reindex(index) 

print (df2.dtypes) 
A  object 
B float64 
C float64 
dtype: object 

Кроме того, если я пытаюсь ресэмплировать

df3 = df.resample('Min')

int64 превратится в float64 и по какой-то причине я потеряю object колонку.

print (df3.dtypes)

print (df3.dtypes) 
B float64 
C float64 
dtype: object 

Так как я хочу, чтобы интерполировать столбцы по-разному на основе этого различия в последующей стадии (после конкатенации df с другим df), мне нужно, чтобы они сохранить свою первоначальную dtype. У моего реального df есть гораздо больше столбцов каждого типа, по этой причине я ищу решение, которое не зависит от вызова столбцов индивидуально по их метке.

Есть ли способ поддерживать их dtype во время переиндексации? Или есть способ, каким образом я могу назначить им их dtype (они являются единственными столбцами, состоящими только из целых чисел, кроме NAN)? Может ли кто-нибудь мне помочь?

ответ

3

Это impossible, потому что если вы получаете по крайней мере один NaN значение в некотором столбце int преобразуется в float.

index = pd.date_range(df.index[0], df.index[-1], freq="min") 
df2 = df.reindex(index) 

print (df2) 
         A  B C 
2016-10-08 13:57:00 in 5.61 1.0 
2016-10-08 13:58:00 NaN NaN NaN 
2016-10-08 13:59:00 NaN NaN NaN 
2016-10-08 14:00:00 NaN NaN NaN 
2016-10-08 14:01:00 NaN NaN NaN 
2016-10-08 14:02:00 in 8.05 1.0 
2016-10-08 14:03:00 NaN NaN NaN 
2016-10-08 14:04:00 NaN NaN NaN 
2016-10-08 14:05:00 NaN NaN NaN 
2016-10-08 14:06:00 NaN NaN NaN 
2016-10-08 14:07:00 in 7.92 0.0 
2016-10-08 14:08:00 NaN NaN NaN 
2016-10-08 14:09:00 NaN NaN NaN 
2016-10-08 14:10:00 NaN NaN NaN 
2016-10-08 14:11:00 NaN NaN NaN 
2016-10-08 14:12:00 in 7.98 0.0 
2016-10-08 14:13:00 NaN NaN NaN 
2016-10-08 14:14:00 NaN NaN NaN 
2016-10-08 14:15:00 NaN NaN NaN 
2016-10-08 14:16:00 NaN NaN NaN 
2016-10-08 14:17:00 out 8.18 0.0 

print (df2.dtypes) 
A  object 
B float64 
C float64 
dtype: object 

Но если параметр использования fill_value в reindex, dtypes не изменились:

index = pd.date_range(df.index[0], df.index[-1], freq="min") 
df2 = df.reindex(index, fill_value=0) 

print (df2) 
         A  B C 
2016-10-08 13:57:00 in 5.61 1 
2016-10-08 13:58:00 0 0.00 0 
2016-10-08 13:59:00 0 0.00 0 
2016-10-08 14:00:00 0 0.00 0 
2016-10-08 14:01:00 0 0.00 0 
2016-10-08 14:02:00 in 8.05 1 
2016-10-08 14:03:00 0 0.00 0 
2016-10-08 14:04:00 0 0.00 0 
2016-10-08 14:05:00 0 0.00 0 
2016-10-08 14:06:00 0 0.00 0 
2016-10-08 14:07:00 in 7.92 0 
2016-10-08 14:08:00 0 0.00 0 
2016-10-08 14:09:00 0 0.00 0 
2016-10-08 14:10:00 0 0.00 0 
2016-10-08 14:11:00 0 0.00 0 
2016-10-08 14:12:00 in 7.98 0 
2016-10-08 14:13:00 0 0.00 0 
2016-10-08 14:14:00 0 0.00 0 
2016-10-08 14:15:00 0 0.00 0 
2016-10-08 14:16:00 0 0.00 0 
2016-10-08 14:17:00 out 8.18 0 

print (df2.dtypes) 
A  object 
B float64 
C  int64 
dtype: object 

Лучше использовать method='ffill в reindex:

index = pd.date_range(df.index[0], df.index[-1], freq="min") 
df2 = df.reindex(index, method='ffill') 

print (df2) 
         A  B C 
2016-10-08 13:57:00 in 5.61 1 
2016-10-08 13:58:00 in 5.61 1 
2016-10-08 13:59:00 in 5.61 1 
2016-10-08 14:00:00 in 5.61 1 
2016-10-08 14:01:00 in 5.61 1 
2016-10-08 14:02:00 in 8.05 1 
2016-10-08 14:03:00 in 8.05 1 
2016-10-08 14:04:00 in 8.05 1 
2016-10-08 14:05:00 in 8.05 1 
2016-10-08 14:06:00 in 8.05 1 
2016-10-08 14:07:00 in 7.92 0 
2016-10-08 14:08:00 in 7.92 0 
2016-10-08 14:09:00 in 7.92 0 
2016-10-08 14:10:00 in 7.92 0 
2016-10-08 14:11:00 in 7.92 0 
2016-10-08 14:12:00 in 7.98 0 
2016-10-08 14:13:00 in 7.98 0 
2016-10-08 14:14:00 in 7.98 0 
2016-10-08 14:15:00 in 7.98 0 
2016-10-08 14:16:00 in 7.98 0 
2016-10-08 14:17:00 out 8.18 0 

print (df2.dtypes) 
A  object 
B float64 
C  int64 
dtype: object 

Если использование resample, вы можете получить столбец A назад unstack и stack, но unfortuntely есть еще проблема с float:

df3 = df.set_index('A', append=True) 
     .unstack() 
     .resample('Min', fill_method='ffill') 
     .stack() 
     .reset_index(level=1) 
print (df3) 
         A  B C 
DATE_TIME       
2016-10-08 13:57:00 in 5.61 1.0 
2016-10-08 13:58:00 in 5.61 1.0 
2016-10-08 13:59:00 in 5.61 1.0 
2016-10-08 14:00:00 in 5.61 1.0 
2016-10-08 14:01:00 in 5.61 1.0 
2016-10-08 14:02:00 in 8.05 1.0 
2016-10-08 14:03:00 in 8.05 1.0 
2016-10-08 14:04:00 in 8.05 1.0 
2016-10-08 14:05:00 in 8.05 1.0 
2016-10-08 14:06:00 in 8.05 1.0 
2016-10-08 14:07:00 in 7.92 0.0 
2016-10-08 14:08:00 in 7.92 0.0 
2016-10-08 14:09:00 in 7.92 0.0 
2016-10-08 14:10:00 in 7.92 0.0 
2016-10-08 14:11:00 in 7.92 0.0 
2016-10-08 14:12:00 in 7.98 0.0 
2016-10-08 14:13:00 in 7.98 0.0 
2016-10-08 14:14:00 in 7.98 0.0 
2016-10-08 14:15:00 in 7.98 0.0 
2016-10-08 14:16:00 in 7.98 0.0 
2016-10-08 14:17:00 out 8.18 0.0 

print (df3.dtypes) 
A  object 
B float64 
C float64 
dtype: object 

Я пытаюсь изменить предыдущий answer для литья в `междунар:

int_cols = df.select_dtypes(['int64']).columns 
print (int_cols) 
Index(['C'], dtype='object') 

index = pd.date_range(df.index[0], df.index[-1], freq="s") 
df2 = df.reindex(index) 

for col in df2: 
    if col == int_cols: 
     df2[col].ffill(inplace=True) 
     df2[col] = df2[col].astype(int) 
    elif df2[col].dtype == float: 
     df2[col].interpolate(inplace=True) 
    else: 
     df2[col].ffill(inplace=True) 

#print (df2) 

print (df2.dtypes) 
A  object 
B float64 
C  int32 
dtype: object 
+0

Спасибо так много! Думаю, теперь моя проблема заключается в том, что я не могу линейно интерполировать 'float64' как следующий шаг, потому что все вновь созданные временные метки заполняются. [Ссылка] (HTTP: // StackOverflow.ком/вопросы/39176402/повышающая дискретизация-а-временных рядов-с различными условиями-For-float64-против-объекта-и-INT). Это ссылка на мой первоначальный вопрос, который я только что сегодня понял, что в принятом решении возникла проблема с dtype, поэтому я разместил этот новый вопрос. Вы думаете, что я действительно хочу, даже возможно? – vera

+1

Я добавляю решение, пожалуйста, проверьте последнее обновление. Спасибо, что приняли! – jezrael

+0

Прохладный! Код работал так на моем примере 'df', но чтобы он работал с моим реальным' df' с несколькими столбцами каждого типа, мне пришлось модифицировать следующую строку 'if col == int_cols.all():' потому что я получил ошибка: 'ValueError: значение истинности массива с более чем одним элементом неоднозначно. Используйте a.any() или a.all() '. Теперь, похоже, все работает отлично! Еще раз спасибо! – vera