Pandas: связь между фреймом данных и массивом numpy.ar, используемым для его определения - PullRequest
0 голосов
/ 22 октября 2018

Я просто хотел создать два фрейма данных одинаковых размеров, которые изначально были пустыми.Я сделал это следующим образом:

import numpy as np
import pandas as pd

m = np.empty((2, 3))*np.nan
df1 = pd.DataFrame(m)
df2 = pd.DataFrame(m)

Но когда я изменил определенное значение в одном фрейме данных, это затронуло все три объекта:

df2.iloc[1, 2] = 1

print(df2)
    0   1    2
0 NaN NaN  NaN
1 NaN NaN  1.0

print(df1)
    0   1    2
0 NaN NaN  NaN
1 NaN NaN  1.0

print(m)
array([[nan, nan, nan],
       [nan, nan,  1.]])

Так что, похоже, фрейм данныхпросто обертка вокруг пустого массива: копия не создается.Я нигде не видел такого поведения, документированного, и я просто хотел указать на это.Есть комментарии?

Ответы [ 3 ]

0 голосов
/ 22 октября 2018

Существует аргумент init в DataFrame, который позволяет указать копирование данных из ndarray в DataFrame.

См. Исходный код панд frame.py ,строка 405 и более поздние ... По умолчанию копирование имеет значение False.

Таким образом, вы можете принудительно копировать что-то вроде:

import numpy as np
import pandas as pd

m = np.empty((2, 3))*np.nan
df1 = pd.DataFrame(m,copy=True)
df2 = pd.DataFrame(m)

df2.iloc[1, 2] = 1
print(df1)
print(df2)
0 голосов
/ 22 октября 2018

Идея такого поведения заключается в том, что numpy и pandas предназначены для повышения эффективности.Таким образом, философия разработчиков такова: содержимое копируется только при необходимости .

Например:

a=np.ones((2,3))
df=pd.DataFrame(a)
df.iloc[0,0]="string" 

In [2]: a
Out[2]: 
array([[ 1.,  1.,  1.],
       [ 1.,  1.,  1.]])

In [3]: df
Out[3]: 
        0    1    2
0  string  1.0  1.0
1       1  1.0  1.0

в этом случае создается копия, так как dtypes изменяются.

0 голосов
/ 22 октября 2018

Я думаю, что это происходит потому, что df1 и df2 являются указателями на один и тот же адрес памяти.Если вы не знакомы с указателями, посмотрите, например, this .
. Быстрый способ решения проблемы - скопировать общий массив numpy в новый массив:

 import numpy as np
import pandas as pd

m = np.empty((2, 3))*np.nan
n = m.copy()
df1 = pd.DataFrame(m)
df2 = pd.DataFrame(n)

df2.iloc[1, 2] = 1

print(df1)
print(df2)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...