我对论点有点糊涂copy在DataFrame.merge()后一个同事问我这个问题.
的文档字符串DataFrame.merge()状态:
copy : boolean, default True
If False, do not copy data unnecessarily
Run Code Online (Sandbox Code Playgroud)
该大熊猫文档状态:
copy:始终True从传递的DataFrame对象复制数据(默认),即使不需要重建索引也是如此.在许多情况下无法避免,但可能会提高性能/内存使用率.可以避免复制的情况在某种程度上是病态的,但仍然提供了这种选择.
文档字符串意味着复制数据不是必需的,并且几乎总是可以跳过.另一方面,该文件说,在许多情况下无法避免复制数据.
我的问题是:
And*_*eak 16
免责声明:我对大熊猫不是很有经验,这是我第一次挖掘它的来源,所以我不能保证我在下面的评估中没有遗漏任何东西.
最近重构了相关的代码位.我将根据当前稳定版本0.20讨论该主题,但我不怀疑与早期版本相比的功能变化.
调查始于源merge在大熊猫/核心/重塑/ merge.py(原熊猫/工具/ merge.py).忽略一些doc-aware装饰器:
def merge(left, right, how='inner', on=None, left_on=None, right_on=None,
left_index=False, right_index=False, sort=False,
suffixes=('_x', '_y'), copy=True, indicator=False):
op = _MergeOperation(left, right, how=how, on=on, left_on=left_on,
right_on=right_on, left_index=left_index,
right_index=right_index, sort=sort, suffixes=suffixes,
copy=copy, indicator=indicator)
return op.get_result()
Run Code Online (Sandbox Code Playgroud)
调用merge会将copy参数传递给类_MergeOperation的构造函数,然后调用其get_result()方法.带有上下文的前几行:
# TODO: transformations??
# TODO: only copy DataFrames when modification necessary
class _MergeOperation(object):
[...]
Run Code Online (Sandbox Code Playgroud)
现在第二条评论非常可疑.继续前进,copykwarg 绑定了一个同名的实例属性,它似乎只在类中重新出现一次:
result_data = concatenate_block_managers(
[(ldata, lindexers), (rdata, rindexers)],
axes=[llabels.append(rlabels), join_index],
concat_axis=0, copy=self.copy)
Run Code Online (Sandbox Code Playgroud)
然后,我们可以跟踪的concatenate_block_managers在大熊猫/核心/ internals.py功能,仅仅通过对copykwarg来concatenate_join_units.
我们到达原始copy关键字参数的最后安息点concatenate_join_units:
if len(to_concat) == 1:
# Only one block, nothing to concatenate.
concat_values = to_concat[0]
if copy and concat_values.base is not None:
concat_values = concat_values.copy()
else:
concat_values = _concat._concat_compat(to_concat, axis=concat_axis)
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,唯一copy能做的就是concat_values在连接的特殊情况下将此处的副本重新绑定到相同的名称,而实际上没有任何内容可以连接.
现在,在这一点上,我缺乏熊猫知识开始显示,因为我不确定调用堆栈内部究竟发生了什么.但与上述热山芋方案copy中的串联作用的是无操作状分支结束关键字参数与上面的"TODO"的评论中,完全一致的问题,引用文档:
copy:始终从传递的DataFrame对象复制数据(默认为True),即使不需要重建索引也是如此.在许多情况下无法避免,但可能会提高性能/内存使用率.可以避免复制的情况在某种程度上是病态的,但仍然提供了这种选择.
IIRC我认为复制参数在这里只是一个简单的合并,你实际上想要它被复制(我喜欢带有相同索引的reindex)
基于这些提示,我怀疑在绝大多数实际用例中复制是不可避免的,并且copy从不使用关键字参数.然而,由于少数例外跳过副本的步骤可能会提高性能(不会导致任何性能影响任何为广大的用例的平均时间),选择实施.
我怀疑的理由是这样的:如果不这样做,除非必要的副本(只可能在一个非常特殊的少数情况下)的好处是,代码避免这种情况下,一些内存分配和拷贝,但不能返回副本在非常特殊的情况下,如果不希望变异的返回值merge以任何方式影响原始数据帧,可能会导致意外的意外.因此,copy关键字参数的默认值是True,因此用户只有在merge明确志愿为此时才会获得副本(但即便如此,他们仍然可能最终获得副本).
| 归档时间: |
|
| 查看次数: |
3139 次 |
| 最近记录: |