Создать пустой фреймворк в Pandas с указанием типов столбцов
Я пытаюсь создать пустой фрейм данных с индексом и указать типы столбцов. Способ, которым я это делаю, следующий:
df = pd.DataFrame(index=['pbp'],columns=['contract',
'state_and_county_code',
'state',
'county',
'starting_membership',
'starting_raw_raf',
'enrollment_trend',
'projected_membership',
'projected_raf'],
dtype=['str', 'str', 'str', 'str', 'int', 'float', 'float', 'int', 'float'])
Однако я получаю следующую ошибку:
TypeError: data type not understood
Что это значит?
Ответы
Ответ 1
Это действительно пахнет ошибкой.
Здесь другое (более простое) решение.
import pandas as pd
import numpy as np
def df_empty(columns, dtypes, index=None):
assert len(columns)==len(dtypes)
df = pd.DataFrame(index=index)
for c,d in zip(columns, dtypes):
df[c] = pd.Series(dtype=d)
return df
df = df_empty(['a', 'b'], dtypes=[np.int64, np.int64])
print(list(df.dtypes)) # int64, int64
Ответ 2
Просто замечание.
Вы можете обойти Type Error с помощью np.dtype
:
pd.DataFrame(index = ['pbp'], columns = ['a','b'], dtype = np.dtype([('str','float')]))
но вместо этого вы получаете:
NotImplementedError: compound dtypes are not implementedin the DataFrame constructor
Ответ 3
Я нашел этот вопрос, столкнувшись с тем же вопросом. Я предпочитаю следующее решение (Python 3) для создания пустого DataFrame без индекса.
import numpy as np
import pandas as pd
def make_empty_typed_df(dtype):
tdict = np.typeDict
types = tuple(tdict.get(t, t) for (_, t, *__) in dtype)
if any(t == np.void for t in types):
raise NotImplementedError('Not Implemented for columns of type "void"')
return pd.DataFrame.from_records(np.array([tuple(t() for t in types)], dtype=dtype)).iloc[:0, :]
Тестирование этого...
from itertools import chain
dtype = [('col%d' % i, t) for i, t in enumerate(chain(np.typeDict, set(np.typeDict.values())))]
dtype = [(c, t) for (c, t) in dtype if (np.typeDict.get(t, t) != np.void) and not isinstance(t, int)]
print(make_empty_typed_df(dtype))
Из:
Empty DataFrame
Columns: [col0, col6, col16, col23, col24, col25, col26, col27, col29, col30, col31, col32, col33, col34, col35, col36, col37, col38, col39, col40, col41, col42, col43, col44, col45, col46, col47, col48, col49, col50, col51, col52, col53, col54, col55, col56, col57, col58, col60, col61, col62, col63, col64, col65, col66, col67, col68, col69, col70, col71, col72, col73, col74, col75, col76, col77, col78, col79, col80, col81, col82, col83, col84, col85, col86, col87, col88, col89, col90, col91, col92, col93, col95, col96, col97, col98, col99, col100, col101, col102, col103, col104, col105, col106, col107, col108, col109, col110, col111, col112, col113, col114, col115, col117, col119, col120, col121, col122, col123, col124, ...]
Index: []
[0 rows x 146 columns]
И типы данных...
print(make_empty_typed_df(dtype).dtypes)
Из:
col0 timedelta64[ns]
col6 uint16
col16 uint64
col23 int8
col24 timedelta64[ns]
col25 bool
col26 complex64
col27 int64
col29 float64
col30 int8
col31 float16
col32 uint64
col33 uint8
col34 object
col35 complex128
col36 int64
col37 int16
col38 int32
col39 int32
col40 float16
col41 object
col42 uint64
col43 object
col44 int16
col45 object
col46 int64
col47 int16
col48 uint32
col49 object
col50 uint64
...
col144 int32
col145 bool
col146 float64
col147 datetime64[ns]
col148 object
col149 object
col150 complex128
col151 timedelta64[ns]
col152 int32
col153 uint8
col154 float64
col156 int64
col157 uint32
col158 object
col159 int8
col160 int32
col161 uint64
col162 int16
col163 uint32
col164 object
col165 datetime64[ns]
col166 float32
col167 bool
col168 float64
col169 complex128
col170 float16
col171 object
col172 uint16
col173 complex64
col174 complex128
dtype: object
Добавление индекса становится сложным, потому что для большинства типов данных нет истинного отсутствующего значения, поэтому они получают отливку от какого-либо другого типа с собственным отсутствующим значением (например, int
передаются в float
или object
s), но если у вас есть полные данные о типах, которые вы указали, вы всегда можете вставлять строки по мере необходимости, и ваши типы будут соблюдаться. Это можно сделать с помощью:
df.loc[index, :] = new_row
Опять же, как отметил @Hun, это НЕ, как предполагается Pandas.
Ответ 4
pandas не предлагает чистый целочисленный столбец. Вы можете использовать столбец float и преобразовать этот столбец в целое число по мере необходимости или рассматривать его как объект. То, что вы пытаетесь реализовать, не означает, что предполагается использовать pandas. Но если вы ДЕЙСТВИТЕЛЬНО ДЕЙСТВИТЕЛЬНО хотите этого, вы можете обойти сообщение TypeError, выполнив это.
df1 = pd.DataFrame(index=['pbp'], columns=['str1','str2','str2'], dtype=str)
df2 = pd.DataFrame(index=['pbp'], columns=['int1','int2'], dtype=int)
df3 = pd.DataFrame(index=['pbp'], columns=['flt1','flt2'], dtype=float)
df = pd.concat([df1, df2, df3], axis=1)
str1 str2 str2 int1 int2 flt1 flt2
pbp NaN NaN NaN NaN NaN NaN NaN
Вы можете упорядочить порядок col, как вам нравится. Но опять же, это не способ использования pandas.
df.dtypes
str1 object
str2 object
str2 object
int1 object
int2 object
flt1 float64
flt2 float64
dtype: object
Обратите внимание, что int рассматривается как объект.
Ответ 5
Вы можете сделать это, передав словарь в конструктор DataFrame:
df = pd.DataFrame(index=['pbp'],
data={'contract' : np.full(1, "", dtype=str),
'starting_membership' : np.full(1, np.nan, dtype=float),
'projected_membership' : np.full(1, np.nan, dtype=int)
}
)
Это правильно даст вам фреймворк данных, который выглядит следующим образом:
contract projected_membership starting_membership
pbp "" NaN -9223372036854775808
С dtypes:
contract object
projected_membership float64
starting_membership int64
Тем не менее, есть две вещи, которые следует отметить:
1) str
не является фактически типом, который может обрабатывать столбец DataFrame; вместо этого он возвращается к общему случаю object
. Он будет работать нормально.
2) Почему вы не видите NaN
под starting_membership
? Ну, NaN
определяется только для поплавков; для целых чисел нет значения "Нет", поэтому он отличает np.NaN
от целого. Если вы хотите другое значение по умолчанию, вы можете изменить это в вызове np.full
.
Ответ 6
Вы можете сделать это так
import numpy
import pandas
dtypes = numpy.dtype([
('a', str),
('b', int),
('c', float),
('d', numpy.datetime64),
])
data = numpy.empty(0, dtype=dtypes)
df = pandas.DataFrame(data)
Ответ 7
Это старый вопрос, но я не вижу твердого ответа (хотя @eric_g был очень близок).
Вам просто нужно создать пустой фреймворк со списком пар слова слова: значение. Ключ - это имя столбца, а значение - пустой тип данных.
Поэтому в вашем примере набора данных это выглядит следующим образом:
df = pd.DataFrame(,columns=[{'contract':'',
'state_and_county_code':'',
'state':'',
'county':'',
'starting_membership':int(),
'starting_raw_raf':float(),
'enrollment_trend':float(),
'projected_membership':int(),
'projected_raf':float(),
'pbp':int() #just guessing on this data type
}]).set_index=("pbp")
Ответ 8
Я нашел самый простой обходной путь для меня, это просто объединить список пустых рядов для каждого отдельного столбца:
import pandas as pd
columns = ['contract',
'state_and_county_code',
'state',
'county',
'starting_membership',
'starting_raw_raf',
'enrollment_trend',
'projected_membership',
'projected_raf']
dtype = ['str', 'str', 'str', 'str', 'int', 'float', 'float', 'int', 'float']
df = pd.concat([pd.Series(name=col, dtype=dt) for col, dt in zip(columns, dtype)], axis=1)
df.info()
# <class 'pandas.core.frame.DataFrame'>
# Index: 0 entries
# Data columns (total 9 columns):
# contract 0 non-null object
# state_and_county_code 0 non-null object
# state 0 non-null object
# county 0 non-null object
# starting_membership 0 non-null int32
# starting_raw_raf 0 non-null float64
# enrollment_trend 0 non-null float64
# projected_membership 0 non-null int32
# projected_raf 0 non-null float64
# dtypes: float64(3), int32(2), object(4)
# memory usage: 0.0+ bytes