很多时候,我有一个很大的数据库df
来保存基本数据,并且需要创建更多的列来保存由基本数据列计算的派生数据。
我可以在Pandas中这样做:
df['derivative_col1'] = df['basic_col1'] + df['basic_col2']
df['derivative_col2'] = df['basic_col1'] * df['basic_col2']
....
df['derivative_coln'] = func(list_of_basic_cols)
Pandas将一次性为所有派生列计算和分配内存。
我现在想要的是有一个懒惰的评估机制,将派生列的计算和内存分配推迟到实际需要的时刻。将lazy_eval_columns定义为:
df['derivative_col1'] = pandas.lazy_eval(df['basic_col1'] + df['basic_col2'])
df['derivative_col2'] = pandas.lazy_eval(df['basic_col1'] * df['basic_col2'])
这将像Python 'yield'生成器一样保存时间/内存,因为如果我发出df['derivative_col2']
命令,只会触发特定的计算和内存分配。
如何在Pandas中实现lazy_eval()
?任何提示/想法/参考都欢迎。
3条答案
按热度按时间z9smfwbn1#
从0.13开始(很快就会发布),你可以这样做。这是使用生成器来计算动态公式。通过eval进行内联赋值将是0.13中的一个附加特性,请参见here
创建一个使用
eval
计算公式的生成器;赋值结果,然后产生结果。在行动
所以它的用户决定了评估的顺序(而不是按需)。理论上,
numba
将支持这一点,因此pandas可能会作为eval
的后端(目前使用numexpr进行即时计算)来支持这一点。我的2C。
lazy evaluation很好,但是可以很容易地通过使用python自己的continuation/generate特性来实现,所以将其构建到pandas中,虽然可能,但相当棘手,并且需要一个非常好的用例才能普遍有用。
monwx1rj2#
您可以子类化
DataFrame
,并将列作为属性添加。比如说,调用该属性(通过下面的
x.derivative_col1
)调用LazyFrame中定义的derivative_col1
函数。此函数计算结果并将派生列添加到LazyFrame示例:请注意,如果修改基本列:
派生列不自动更新:
但如果您访问属性,则会重新计算值:
lzfw57am3#
在对Pandas的数据结构进行任何修改或扩展之前,最好使用Dask或Apache Spark等库来减轻进程负载。
Pandas的文档提出了一些扩展其数据结构的替代方案:
在考虑对pandas数据结构进行子类化之前,有一些更简单的替代方案。
子类化pandas.DataFrame
使用
让我们假设您已经有了名为
df
的DataFrame
(根据下面的CustomDataFrame
类定义构造),并填充了数据(出于本示例的目的)类定义
为简单起见,
all_columns
方法定义假设这里只有一个列级别。请在评论中对上述代码提出任何修改建议。