如果指定列中的标志(匹配前6个字母)为“1”,那么将数据转换为NaN的方法是什么?

时间:2017-02-08 05:56:04

标签: python pandas conditional flags

如果指定列中的标志(匹配前6个字母)为“1”,那么将数据转换为NaN的方法是什么?

有数据帧表示数据和标志。 两个数据帧之间的列顺序不同。

这些帧有数百列和50万条记录。

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 个答案:

答案 0 :(得分:3)

    {li> split'.'
  • add df2.where(df2 == 0)
    • 将为零,其中n和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

答案 1 :(得分: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

答案 2 :(得分: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')