Подтвердить что ты не робот

Есть ли способ скопировать только структуру (а не данные) Pandas DataFrame?

Я откуда-то получил DataFrame и хочу создать еще один DataFrame с тем же числом и именами столбцов и строк (индексов). Например, предположим, что исходный фрейм данных был создан как

import pandas as pd
df1 = pd.DataFrame([[11,12],[21,22]], columns=['c1','c2'], index=['i1','i2'])

Я скопировал структуру, явно указав столбцы и имена:

df2 = pd.DataFrame(columns=df1.columns, index=df1.index)    

Я не хочу копировать данные, иначе я мог бы просто написать df2 = df1.copy(). Другими словами, после создания df2 он должен содержать только элементы NaN:

In [1]: df1
Out[1]: 
    c1  c2
i1  11  12
i2  21  22

In [2]: df2
Out[2]: 
     c1   c2
i1  NaN  NaN
i2  NaN  NaN

Есть ли более идиоматический способ сделать это?

4b9b3361

Ответ 1

Начнем с некоторых примеров данных

In [1]: import pandas as pd

In [2]: df = pd.DataFrame([[1, 'a'], [2, 'b'], [3, 'c']],
   ...:                   columns=['num', 'char'])

In [3]: df
Out[3]: 
   num char
0    1    a
1    2    b
2    3    c

In [4]: df.dtypes
Out[4]: 
num      int64
char    object
dtype: object

Теперь можно использовать простую инициализацию DataFrame, используя столбцы исходного DataFrame, но не предоставляя никаких данных:

In [5]: empty_copy_1 = pd.DataFrame(data=None, columns=df.columns)

In [6]: empty_copy_1
Out[6]: 
Empty DataFrame
Columns: [num, char]
Index: []

In [7]: empty_copy_1.dtypes
Out[7]: 
num     object
char    object
dtype: object

Как вы можете видеть, типы данных столбцов не совпадают, как в исходном DataFrame.

Итак, если вы хотите сохранить столбец dtype...

Если вы хотите сохранить типы данных столбцов, вам нужно построить DataFrame один Series за раз

In [8]: empty_copy_2 = pd.DataFrame.from_items([
   ...:     (name, pd.Series(data=None, dtype=series.dtype))
   ...:     for name, series in df.iteritems()])

In [9]: empty_copy_2
Out[9]: 
Empty DataFrame
Columns: [num, char]
Index: []

In [10]: empty_copy_2.dtypes
Out[10]: 
num      int64
char    object
dtype: object

Ответ 2

В версия 0.18 из pandas конструктор DataFrame не имеет параметров для создания фрейма данных, например, другого блока данных с NaN вместо значений.

Код, который вы используете df2 = pd.DataFrame(columns=df1.columns, index=df1.index), является наиболее логичным способом, единственный способ улучшить его - еще раз указать, что вы делаете, это добавить data=None, чтобы другие кодеры сразу видели, что вы намеренно уходите из данных нового созданного DataFrame.

TL;DR: Итак, мое предложение:

Явный лучше, чем неявный

df2 = pd.DataFrame(data=None, columns=df1.columns, index=df1.index)

Очень похож на ваш, но более подробно.

Ответ 3

Это работа для reindex_like. Начните с оригинала:

df1 = pd.DataFrame([[11, 12], [21, 22]], columns=['c1', 'c2'], index=['i1', 'i2'])

Создайте пустой DataFrame и переиндексируйте его как df1:

pd.DataFrame().reindex_like(df1)
Out: 
    c1  c2
i1 NaN NaN
i2 NaN NaN   

Ответ 4

Вы можете просто mask на notna() i.e

df1 = pd.DataFrame([[11, 12], [21, 22]], columns=['c1', 'c2'], index=['i1', 'i2'])

df2 = df1.mask(df1.notna())

    c1  c2
i1 NaN NaN
i2 NaN NaN

Ответ 5

Простая альтернатива - сначала скопируйте базовую структуру или индексы и столбцы с типом данных из исходного фрейма данных (df1) в df2

df2 = df1.iloc[0:0]

Затем заполните ваш фреймворк пустыми строками - псевдокодом, который нужно будет адаптировать, чтобы лучше соответствовать вашей фактической структуре:

s = pd.Series([Nan,Nan,Nan], index=['Col1', 'Col2', 'Col3'])

цикл через строки в df1

df2 = df2.append(s)