Python 如何在不复制数据的情况下连接数据帧?

Python 如何在不复制数据的情况下连接数据帧?,python,pandas,Python,Pandas,我想在不复制数据的情况下连接两个数据帧。也就是说,我希望连接的数据帧是两个原始数据帧中数据的视图。我尝试使用concat(),但没有成功。此代码块显示更改基础数据会影响连接的两个数据帧,但不会影响连接的数据帧: arr = np.random.randn(12).reshape(6, 2) df = pd.DataFrame(arr, columns = ('VALE5', 'PETR4'), index = dates) arr2 = np.random.randn(12).reshape(6

我想在不复制数据的情况下连接两个数据帧。也就是说,我希望连接的数据帧是两个原始数据帧中数据的视图。我尝试使用concat(),但没有成功。此代码块显示更改基础数据会影响连接的两个数据帧,但不会影响连接的数据帧:

arr = np.random.randn(12).reshape(6, 2)
df = pd.DataFrame(arr, columns = ('VALE5', 'PETR4'), index = dates)
arr2 = np.random.randn(12).reshape(6, 2)
df2 = pd.DataFrame(arr, columns = ('AMBV3', 'BBDC4'), index = dates)
df_concat = pd.concat(dict(A = df, B = df2),axis=1)
pp(df)
pp(df_concat)
arr[0, 0] = 9999999.99
pp(df)
pp(df_concat)
这是最后五行的输出。将新值分配给arr[0,0]后,df发生变化;df_concat未受影响

In [56]: pp(df)
           VALE5     PETR4
2013-01-01 -0.557180  0.170073
2013-01-02 -0.975797  0.763136
2013-01-03 -0.913254  1.042521
2013-01-04 -1.973013 -2.069460
2013-01-05 -1.259005  1.448442
2013-01-06 -0.323640  0.024857

In [57]: pp(df_concat)
               A                   B          
           VALE5     PETR4     AMBV3     BBDC4
2013-01-01 -0.557180  0.170073 -0.557180  0.170073
2013-01-02 -0.975797  0.763136 -0.975797  0.763136
2013-01-03 -0.913254  1.042521 -0.913254  1.042521
2013-01-04 -1.973013 -2.069460 -1.973013 -2.069460
2013-01-05 -1.259005  1.448442 -1.259005  1.448442
2013-01-06 -0.323640  0.024857 -0.323640  0.024857

In [58]: arr[0, 0] = 9999999.99

In [59]: pp(df)
                 VALE5     PETR4
2013-01-01  9999999.990000  0.170073
2013-01-02       -0.975797  0.763136
2013-01-03       -0.913254  1.042521
2013-01-04       -1.973013 -2.069460
2013-01-05       -1.259005  1.448442
2013-01-06       -0.323640  0.024857

In [60]: pp(df_concat)
               A                   B          
           VALE5     PETR4     AMBV3     BBDC4
2013-01-01 -0.557180  0.170073 -0.557180  0.170073
2013-01-02 -0.975797  0.763136 -0.975797  0.763136
2013-01-03 -0.913254  1.042521 -0.913254  1.042521
2013-01-04 -1.973013 -2.069460 -1.973013 -2.069460
2013-01-05 -1.259005  1.448442 -1.259005  1.448442
2013-01-06 -0.323640  0.024857 -0.323640  0.024857
我猜这意味着concat()创建了数据的副本。有没有办法避免复制?(我想尽量减少内存使用)

另外,是否有一种快速方法可以检查两个数据帧是否链接到相同的底层数据?(缺少更改数据和检查每个数据帧是否已更改的麻烦)

谢谢你的帮助

FS

你不能(至少很容易)。当您调用
concat
时,最终会调用
np.concatenate

看。它的缺点是不能保证数组在内存中是连续的

这里有一个简单的例子

a = rand(2, 10)
x, y = a
z = vstack((x, y))
print 'x.base is a and y.base is a ==', x.base is a and y.base is a
print 'x.base is z or y.base is z ==', x.base is z or y.base is z
输出:

x.base is a and y.base is a == True
x.base is z or y.base is z == False
(8,)
(16,)
即使
x
y
共享相同的
,即
a
串联
(因此
vstack
)也不能假定它们是相同的,因为人们通常希望串联任意跨距的数组

您可以轻松生成两个具有不同步长的阵列,它们共享相同的内存,如下所示:

a = arange(10)
b = a[::2]
print a.strides
print b.strides
输出:

x.base is a and y.base is a == True
x.base is z or y.base is z == False
(8,)
(16,)
这就是为什么会发生以下情况:

In [214]: a = arange(10)

In [215]: a[::2].view(int16)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-215-0366fadb1128> in <module>()
----> 1 a[::2].view(int16)

ValueError: new type not compatible with array.

In [216]: a[::2].copy().view(int16)
Out[216]: array([0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0], dtype=int16)
[214]中的
:a=arange(10)
在[215]中:a[::2]。视图(int16)
---------------------------------------------------------------------------
ValueError回溯(最近一次调用上次)
在()
---->1A[::2]。视图(int16)
ValueError:新类型与数组不兼容。
在[216]中:a[::2].copy().view(int16)
Out[216]:数组([0,0,0,0,2,0,0,0,0,4,0,0,0,0,6,0,0,0,0,0,8,0,0,0],数据类型=int16)

编辑:
df1.dtype!=df2.dtype
不会复制。否则,将创建一个副本。

目前,检查两个numpy阵列是否共享内存的最佳方法如下:这种行为是错误吗
merge
有一个
copy
参数,因此当我执行
df_concat=df.merge时(df1,left_index=True,right_index=True,copy=False)
如果两个数据帧的索引相同(在这种情况下是正确的,系列对象不必更改,为什么熊猫会复制数据,而我明确指示它不要使用
copy=False
?即使我先创建索引,然后创建
df
df
df_concat
df.index是
df_concat.index`返回
Tru。)e
,数据仍然被复制。我不一定认为这是一个错误。我现在正在研究它。但是应该有更好的文档记录。这不是一个错误;连接总是复制的。没有办法维护视图(当然,如果你想与原始帧相关联,你可以简单地设置子视图)。您到底想实现什么?如果是这样,那么我只是问
merge
函数的
copy
参数做什么?:)如果给定轴上的索引相同,它会尝试避免底层块的副本