如果指定列中的标志(匹配前 6 个字母)为“1”,将数据转换为 NaN 的方法是什么?
What is the method to convert the data into NaN, if the flag in a designated column (matches top 6 letters) is "1"?
如果指定列中的标志(匹配前 6 个字母)为“1”,将数据转换为 NaN 的方法是什么?
有指示数据和标志的数据帧。
两个数据框之间的列顺序不同。
这些框架有数百列和半百万条记录。
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
这是一个table,我想得到:
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
假设您的第二个数组 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')
您可以使用 mask
which create NaN
where True
values with 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
split
列 '.'
add
df2.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
如果指定列中的标志(匹配前 6 个字母)为“1”,将数据转换为 NaN 的方法是什么?
有指示数据和标志的数据帧。 两个数据框之间的列顺序不同。
这些框架有数百列和半百万条记录。
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
这是一个table,我想得到:
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
假设您的第二个数组 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')
您可以使用 mask
which create NaN
where True
values with 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
split
列'.'
add
df2.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