gpt4 book ai didi

python - 用于与多个 boolean 列/系列进行类似集合比较的矢量化 Pandas 方法

转载 作者:行者123 更新时间:2023-12-03 20:46:16 25 4
gpt4 key购买 nike

示例数据说明:

import pandas as pd

animals = pd.DataFrame({'name': ['ostrich', 'parrot', 'platypus'],
'legs': [2, 2, 4],
'flight': [False, True, False],
'beak': [True, True, True],
'feathers': [True, True, False]})


姓名

航类

Feather


鸵鸟
2




鹦鹉
2




鸭嘴兽
4




已经有效的
Pandas 可以很容易地根据条件检查整个列(这是一个系列),结果(一系列 boolean 值)可用于过滤具有 boolean indexing 的数据帧:
bipeds = (animals.legs == 2)
print(animals[bipeds])

name legs flight beak feathers
0 ostrich 2 False True True
1 parrot 2 True True True
在我的用例中,每个这样的条件都是从文本搜索字符串中的一个术语中解析出来的,所以我需要以编程方式构造它们。 (我知道 Pandas 的 query ,但我需要不同的功能。)为此编写一个函数非常简单:
def comp_search(df, column_name, comp, value):
return getattr(df[column_name], f'__{comp}__')(value)

bipeds = comp_search(animals, 'legs', 'eq', 2)
检查任何给定的 boolean 列就像 animals[animals.feathers] 一样简单。 .
我想做的事
我要表演 设置与 boolean 列集合的比较 :例如,查找所有具有至少一组特征或少于一组特征的动物,等等。从前面推断,我可以想象这样的情况:
set(df[features]) <= set(values)
假设这样的条件可以这样构建:
def set_comp_search(df, column_names, comp, values):
return getattr(set(df[column_names]), f'__{comp}__')(set(values))
当然,这些都不起作用,如 set()的数据框创建一组普通的列名。
什么有效,但效率极低
以上可以通过使用 apply 来实现将每行 boolean 值转换为一个集合,然后与生成的一系列集合进行比较:
def row_to_set(row):
return set(label for label, value
in zip(row.index, row)
if value)

def set_comp_search(df, column_names, comp, values):
series_of_sets = df[column_names].apply(row_to_set, axis=1)
return getattr(series_of_sets, f'__{comp}__')(set(values))
简洁明了!不幸的是,使用 apply 进行迭代当源数据帧长到数千行时,速度会变得非常慢。
什么有效,但似乎是重新实现
如果我像这样为每个单独的集合比较硬编码一个等效的 boolean 表达式,则结果比较是矢量化的(在整个列上执行,而不是在 Python 级别迭代)。
def set_comp_search(df, column_names, comp, values):
other_column_names = set(column_names) - set(values)
value_columns = df[values]
other_columns = df[other_column_names]

if comp == 'gt':
# All the searched features, and at least one other
return value_columns.all(axis=1) & other_columns.any(axis=1)

if comp == 'ge':
# All the searched features
return value_columns.all(axis=1)

if comp == 'eq':
# All the searched features, and none other
return value_columns.all(axis=1) & ~other_columns.any(axis=1)

if comp == 'le':
# No other features
return ~other_columns.any(axis=1)

if comp == 'lt':
# Not all of the searched features, and none other
return ~value_columns.all(axis=1) & ~other_columns.any(axis=1)
所以如果我想要一个条件来表示 set(animals[features]) > {'beak'} :
more_than_beak = set_comp_search(animals, {'flight', 'beak', 'feathers'},
'gt', {'beak'})
# Converts to: (animals.beak) & (animals.flight | animals.feathers)
print(animals[more_than_beak])

name legs flight beak feathers
0 ostrich 2 False True True
1 parrot 2 True True True

# Correctly omits the platypus
除了笨拙之外,这运行得足够快。但我觉得我必须重新发明一个轮子。这似乎与 Series.str 的用例大致相似。方法可以,尽管它需要使用数据帧、系列序列或 numpy 数组而不是单个系列进行操作。 (遗憾的是没有 DataFrame.set 模块。)
所以我的问题是: Pandas 是否提供了一种矢量化方法,用于与 boolean 列集合进行类似集合的比较?
(我也看过 this question ,因为它听起来很相似,但它不适用于类似集合的行为。)

最佳答案

在我看来,您可能会从使用 numpy 向量化的函数中受益。以下是此类函数的示例,即矢量化及其应用:

def analyze_birds (name: str, legs: int, feathers: bool):
if feathers and legs == 2 :
return name + "-Feathered Biped"
if legs > 2 :
return name + "-Quadruped"

vector_analyze_birds = np.vectorize(analyze_birds)

animals['Analysis'] = vector_analyze_birds(animals['name'], animals['legs'], animals['feathers'])
Output

关于python - 用于与多个 boolean 列/系列进行类似集合比较的矢量化 Pandas 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65430204/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com