我有以下数据框。 status列将值存储为列表。
DF
STATUS
1 [REQUESTED, RECEIVED]
2 [XYZ]
3 [RECEIVED]
当我尝试以下逻辑时:
df['STATUS'].str.upper().isin(['RECEIVED'])
它给了我
1 False
2 False
3 False
但我期待
1 True
2 False
3 True
因为我们在第1行和第3行有值RECEIVED
答案 0 :(得分:1)
你可能意味着像
这样的东西>>> df.STATUS.astype(str).str.upper().str.contains('RECEIVED')
1 True
2 False
3 False
(你的例子有一个错字,顺便说一句 - 1.已收到,3已收到。)
因为isin
与你的例子的意思相反。
答案 1 :(得分:1)
直接使用列表值进行操作很困难。您可以使用一些分隔符将字符串连接成一个,然后检查条件:
import pandas as pd
df = pd.DataFrame({'STATUS': [['REQUESTED', 'RECEIVED'], ['XYZ'], ['RECEIVED']]},
index=[1, 2, 3])
print(df['STATUS'].str.join('|').str.contains('RECEIVED'))
输出:
1 True
2 False
3 True
Name: STATUS, dtype: bool
更有效的选择是用数字标志替换字符串。自Python 3.6使用enum.Flag
以来,这可以很好地完成。
import enum
import pandas as pd
class Status(enum.Flag):
REQUESTED = enum.auto()
RECEIVED = enum.auto()
XYZ = enum.auto()
df = pd.DataFrame({'STATUS': [Status.REQUESTED | Status.RECEIVED, Status.XYZ, Status.RECEIVED]}, index=[1, 2, 3])
print(df['STATUS'] & Status.RECEIVED)
或者,如果您已经有一个包含字符串的数据框:
import enum
import pandas as pd
from functools import reduce
class Status(enum.Flag):
REQUESTED = enum.auto()
RECEIVED = enum.auto()
XYZ = enum.auto()
df = pd.DataFrame({'STATUS': [['REQUESTED', 'RECEIVED'], ['XYZ'], ['RECEIVED']]}, index=[1, 2, 3])
df['STATUS_ENUM'] = df['STATUS'].apply(lambda v: reduce(lambda a, b: a | Status[b], v, Status(0)))
print(df['STATUS_ENUM'] & Status.RECEIVED)
答案 2 :(得分:1)
对于这样的简单检查,您可以加入字符串列表并使用contains
。
编辑:
为了说明RECEIVED
和RECEIVED CASH
之间的差异,您可以使用唯一字符(例如'='
)加入列表并围绕具有相同字符的结果字符串,然后检查=RECEIVED=
。
('=' + df['STATUS'].str.join('=') + '=').str.contains('=RECEIVED=')
答案 3 :(得分:1)
来自jde的数据
\[\begin{array}{lllll}...\end{array}\]