如果指定列中的标志(匹配前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
答案 0 :(得分:3)
split
列'.'
add
df2.where(df2 == 0)
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')