2017-02-08 18 views
2

Что такое метод преобразования данных в NaN, если флаг в указанном столбце (соответствует верхним 6 буквам) равен «1»?Что такое метод преобразования данных в NaN, если флаг в указанном столбце (соответствует верхним 6 буквам) равен «1»?

Существуют Dataframes, которые указывают данные и флаги. Порядок столбцов различается между двумя кадрами данных.

Эти рамки имеют сотни столбцов и полмиллиона записей.

df 
        123456.A 123456.B ... 456789.A 456789.B 
2016-01-01 00:00   5.6  0.3 ...  6.7  1.1 
2016-01-01 00:01   5.4  0.4 ...  6.7  1.3 
2016-01-01 00:02   5.1  0.2 ...  6.7  1.5 
.... 
2016-12-31 23:57   5.7  0.4 ...  6.7  1.2 
2016-12-31 23:58   5.6  0.3 ...  6.7  1.4 
2016-12-31 23:59   5.4  0.4 ...  6.7  1.5 

flag_t 
         456789 123456 ... 342546 821453 
2016-01-01 00:00   1   0 ...  0  0 
2016-01-01 00:01   0   0 ...  0  0 
2016-01-01 00:02   1   1 ...  0  0 
.... 
2016-12-31 23:57   0   1 ...  1  1 
2016-12-31 23:58   0   0 ...  0  1 
2016-12-31 23:59   0   0 ...  0  1 

Это таблица, в которой я хотел бы получить:

df 
        123456.A 123456.B ... 456789.A 456789.B 
2016-01-01 00:00   5.6  0.3 ...  NaN  NaN 
2016-01-01 00:01   5.4  0.4 ...  6.7  1.3 
2016-01-01 00:02   NaN  NaN ...  NaN  NaN 
.... 
2016-12-31 23:57   NaN  NaN ...  6.7  1.2 
2016-12-31 23:58   5.6  0.3 ...  6.7  1.4 
2016-12-31 23:59   5.4  0.4 ...  6.7  1.5 

ответ

3
  • split колонны по '.'
  • adddf2.where(df2 == 0)
    • будет равен нулю, где ноль и np.nan еще где.
    • Я делаю это, потому что могу add на определенном уровне, передавая все остальное.

df.columns = df.columns.str.split('.', expand=True) 

df = df.add(df2.where(df2==0), level=0) 

df.columns = df.columns.map('.'.join) 

print(df) 

        123456.A 123456.B 456789.A 456789.B 
2016-01-01 00:00:00  5.6  0.3  NaN  NaN 
2016-01-01 00:01:00  5.4  0.4  6.7  1.3 
2016-01-01 00:02:00  NaN  NaN  NaN  NaN 
2016-12-31 23:57:00  NaN  NaN  6.7  1.2 
2016-12-31 23:58:00  5.6  0.3  6.7  1.4 
2016-12-31 23:59:00  5.4  0.4  6.7  1.5 
+0

Увидеть ответы, подобные этому, всегда весело, потому что это напоминает мне о том, насколько API поверхности 'pandas' имеет то, что я до сих пор не использовал. Интересный материал. –

1

Предполагая, что ваш второй массивом, flag_t является допустимой маской для первого массива, чтобы получить выход вы хотите, вы можете использование pandas.DataFrame.where. Вот небольшой показательный пример:

>>> df = pd.DataFrame({'a': [1,2], 'b':[3,4]}) 
>>> mask = pd.DataFrame({'a': [0, 1], 'b': [1,0]}) 
>>> df.where(mask) 
<<<  a b 
    0 NaN 3.0 
    1 2.0 NaN 

В этом случае загвоздка, что есть две колонки вы маскирующие, названный «A» и «B», таким образом, они не совсем синонимы. Вот один из способов справиться с этим:

df_1 = df[[c for c in df.columns if ".A" in c]] # Get the .A columns... 
      .rename(columns={c: c[:-2] for c in df.columns}) # ...remove the .B... 
      .where(mask) # And apply the mask. 
df_2 = df[[c for c in df.columns if ".B" in c]] # Ditto. 
      .rename(columns={c: c[:-2] for c in df.columns}) 
      .where(mask) 
# Rejoin to get the final result. 
masked_df = df_1.join(df_2, lsuffix='.A', rsuffix='.B') 
+0

Да, я хочу, чтобы повлиять на преобразование всех столбцов в ДФ, если имя столбца из верхних 6 букв совпадает. – Lcy

+0

См. Мой измененный ответ. –

2

Вы можете использовать mask, которые создают NaN где True значения с reindex:

#convert columns to MultiIndex 
df.columns = df.columns.str.split('.', expand=True) 
print (df) 

       123456  456789  
         A B  A B 
2016-01-01 00:00 5.6 0.3 6.7 1.1 
2016-01-01 00:01 5.4 0.4 6.7 1.3 
2016-01-01 00:02 5.1 0.2 6.7 1.5 
2016-12-31 23:57 5.7 0.4 6.7 1.2 
2016-12-31 23:58 5.6 0.3 6.7 1.4 
2016-12-31 23:59 5.4 0.4 6.7 1.5 

#create new MultiIndex with flag_t columns and possible letters 
mux = pd.MultiIndex.from_product([flag_t.columns, ['A','B']]) 
print (mux) 
MultiIndex(levels=[['123456', '342546', '456789', '821453'], ['A', 'B']], 
      labels=[[2, 2, 0, 0, 1, 1, 3, 3], [0, 1, 0, 1, 0, 1, 0, 1]]) 

#reindex flag_t by new MultiIndex mux 
flag_t = flag_t.reindex(columns=mux, level=0) 
print (flag_t) 
       456789 123456 342546 821453 
         A B  A B  A B  A B 
2016-01-01 00:00  1 1  0 0  0 0  0 0 
2016-01-01 00:01  0 0  0 0  0 0  0 0 
2016-01-01 00:02  1 1  1 1  0 0  0 0 
2016-12-31 23:57  0 0  1 1  1 1  1 1 
2016-12-31 23:58  0 0  0 0  0 0  1 1 
2016-12-31 23:59  0 0  0 0  0 0  1 1 
#create mask by reindex, cast to bool 
mask = flag_t.reindex(columns=df.columns).astype(bool) 
print (mask) 
       123456  456789  
         A  B  A  B 
2016-01-01 00:00 False False True True 
2016-01-01 00:01 False False False False 
2016-01-01 00:02 True True True True 
2016-12-31 23:57 True True False False 
2016-12-31 23:58 False False False False 
2016-12-31 23:59 False False False False 


df1 = df.mask(mask) 
#convert MultiIndex to columns 
df1.columns = df1.columns.map('.'.join) 
print (df1) 
        123456.A 123456.B 456789.A 456789.B 
2016-01-01 00:00  5.6  0.3  NaN  NaN 
2016-01-01 00:01  5.4  0.4  6.7  1.3 
2016-01-01 00:02  NaN  NaN  NaN  NaN 
2016-12-31 23:57  NaN  NaN  6.7  1.2 
2016-12-31 23:58  5.6  0.3  6.7  1.4 
2016-12-31 23:59  5.4  0.4  6.7  1.5