pandas 比较列和列表元素以使用pd.DataFrame

oxf4rvwz  于 9个月前  发布在  其他
关注(0)|答案(2)|浏览(79)

我有一个pd.DataFrame,它可能看起来像这样

data = {"col_x": ["1234", "5678", "9876", "1111"],
        "col_y": ["1234", "2222", "3333", "1111"],
        "col_grp": [pd.NA, ["5678", "9999"], ["9876", "5555", "1222"], pd.NA]}

df = pd.DataFrame(data)

字符串
我想做另一列valid来检查col_x是否等于col_ycol_x是否在col_grp中。
我尝试与

def check_validity(row):
    if row["col_x"] == row["col_y"]:
        return True
    if pd.notnull(row["col_grp"]):
        if isinstance(row["col_grp"], list):
            return row["col_x"] in row["col_grp"]
        else:
            return row["col_x"] == row["col_grp"]
    return False

df["valid"] = df.apply(lambda row: check_validity(row), axis=1)


但我得到

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()


我知道list可能不应该在这样的pd.DataFrame中,所以我提前道歉。
有人能帮帮我吗?

jvidinwx

jvidinwx1#

不要使用apply,而是使用一个更有效的列表解析:

df['valid'] = [x==y or isinstance(g, list ) and x in g for (x, y, g)
               in zip(df['col_x'], df['col_y'], df['col_grp'])]

字符串
如果必须使用apply

def check_validity(row):
    x, y, g = row[['col_x', 'col_y', 'col_grp']]
    return x==y or isinstance(g, list ) and x in g

df['valid'] = df.apply(lambda row: check_validity(row), axis=1)


输出(带有一些额外的行):

col_x col_y             col_grp  valid
0  1234  1234                <NA>   True
1  5678  2222        [5678, 9999]   True
2  9876  3333  [9876, 5555, 1222]   True
3  1111  1111                <NA>   True
4  1234  2222                <NA>  False
5  1234  2222              [2222]  False

klh5stk1

klh5stk12#

def check_validity(row):
    if row["col_x"] == row["col_y"]:
        return True
    
    if isinstance(row["col_grp"], list):
        return row["col_x"] in row["col_grp"]
    elif pd.notnull(row["col_grp"]):
        return row["col_x"] == row["col_grp"]
    return False

df["valid"] = df.apply(check_validity, axis=1)

字符串
问题出在null检查上。如果你给予一个列表,而不是一个布尔值,那么pd.notnull返回一个布尔值列表。你可以通过首先检查单元格是否包含列表来解决这个问题。此外,lambda函数的使用是不正确的,你可以直接给予函数。

相关问题