Pandas - 快速访问对象属性列的方法

10

假设我在Python中有一个自定义类,该类具有属性val。如果我有一个pandas数据框,其中包含这些对象的一列,我如何访问此属性并创建一个具有此值的新列?

数据示例:

df
Out[46]: 
row   custom_object
1     foo1
2     foo2
3     foo3
4     foo4
Name: book, dtype: object

当自定义对象为Foo类时:

class Foo:
    def __init__(self, val):
        self.val = val

我所知道的使用实例属性创建新列的唯一方法是使用applylambda组合,在处理大型数据集时速度较慢:

df['custom_val'] = df['custom_object'].apply(lambda x: x.val)

是否有更高效的方法?

2个回答

4
您可以使用列表推导式:
```python ```
df['custom_val'] = [foo.val for foo in df['custom_object']]

时间

# Set-up 100k Foo objects.
vals = [np.random.randn() for _ in range(100000)]
foos = [Foo(val) for val in vals]
df = pd.DataFrame(foos, columns=['custom_object'])

# 1) OP's apply method.
%timeit df['custom_object'].apply(lambda x: x.val)
# 10 loops, best of 3: 26.7 ms per loop

# 2) Using a list comprehension instead.
%timeit [foo.val for foo in df['custom_object']]
# 100 loops, best of 3: 11.7 ms per loop

# 3) For reference with the original list of objects (slightly faster than 2) above).
%timeit [foo.val for foo in foos]
# 100 loops, best of 3: 9.79 ms per loop

# 4) And just on the original list of raw values themselves.
%timeit [val for val in vals]
# 100 loops, best of 3: 4.91 ms per loop

如果你有原始的值列表,你可以直接将它们赋值:
# 5) Direct assignment to list of values.
%timeit df['v'] = vals
# 100 loops, best of 3: 5.88 ms per loop

0

设置代码:

import operator
import random
from dataclasses import dataclass

import numpy as np
import pandas as pd


@dataclass
class SomeObj:
    val: int


df = pd.DataFrame(data={f"col_1": [SomeObj(random.randint(0, 10000)) for _ in range(10000000)]})

解决方案 1

df['col_1'].map(lambda elem: elem.val)

时间:约3.2秒

解决方案2

df['col_1'].map(operator.attrgetter('val'))

时间:约2.7秒

解决方案3

[elem.val for elem in df['col_1']]

时间:约1.4秒

注意:请记住,此解决方案会产生不同的结果类型,在某些情况下可能会成为问题。



网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接