numpy 选择Pandas中的第一个Truthy列

trnvg8h3  于 2023-10-19  发布在  其他
关注(0)|答案(2)|浏览(116)

我正在优化一些代码以提高速度,我明白Pandas中的.apply不是数据处理的最佳方法。我希望以某种方式优化这段代码。
假设你有两个这样的柱子
| 第一套|设置_二|
| --|--|
| 'Foo'|“的一声|
| “的一声|“酒吧”|
| 'Foo'|“酒吧”|
如果我想在apply语句中获得两列中的第一个truthy值,我可以只使用df.apply(lambda x : x.Set_One or x.Set_Two)
这将导致
| 结果|
| --|
| 'Foo'|
| “酒吧”|
| 'Foo'|
但随着数据集的扩大,这种速度会减慢。考虑到这是一个相当简单的比较,没有太多。
一个很好的解决方案是,如果我可以做result = df['Set_One'] or df['Set_Two'],但一个序列的真值是模糊的。使用&|运算符并不考虑真实性(或者在字符串上工作)。
这种比较的最佳做法是什么?
到目前为止,我只尝试了一个向量化函数,它在功能上只返回第一个truthy值。

def return_truthy(val1, val2):
    return val1 or val2

vec_truthy = np.vectorize(return_truthy)

vec_truthy(df['Set_One'], df['Set_Two'])

使用这个函数确实会导致大约10倍的速度提高,但它看起来并不优雅。

s4chpxco

s4chpxco1#

您可以使用numpy.logical_or函数来执行此操作。

import pandas as pd
import numpy as np

df = pd.DataFrame({"Set_One":["Foo", "", "Foo"], 
                   "Set_Two":["", "Bar", "Bar"]})
print(np.logical_or(df["Set_One"], df["Set_Two"]))

输出量:

0    Foo
1    Bar
2    Foo
dtype: object
cbwuti44

cbwuti442#

jared上面说的是我认为最好的方法,我只是想补充一下,这也解决了问题中提到的速度问题。使用以下速度测试

import pandas as pd
import numpy as np
import timeit

# Create a large dataframe
data = {
    "Set_One": ["foo", None, "foo"] * 100000,
    "Set_Two": [None, "bar", "bar"] * 100000,
}
df = pd.DataFrame(data)

# Method 1: Using df.apply
def method1():
    result = df.apply(lambda x: x.Set_One or x.Set_Two, axis=1)

# Method 2: Using np.logical_or
def method2():
    result = np.logical_or(df["Set_One"], df["Set_Two"])

# Measure execution time for method 1
time_method1 = timeit.timeit(method1, number=10)

# Measure execution time for method 2
time_method2 = timeit.timeit(method2, number=10)

print("Time taken using df.apply(lambda x: x.Set_One or x.Set_Two):", time_method1)
print(
    'Time taken using np.logical_or(df["Set_One"], df["Set_Two"]):', time_method2)

times_faster = time_method1 / time_method2
print("Method 2 is", times_faster, "times faster than method 1")

我得到以下结果

Time taken using df.apply(lambda x: x.Set_One or x.Set_Two): 20.352213299999903
Time taken using np.logical_or(df["Set_One"], df["Set_Two"]): 0.05363929999998618
Method 2 is 379.4272725409382 times faster than method 1

相关问题