在Pandas中创建空数据框,指定列类型

Vin*_*ent 46 python 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'])
Run Code Online (Sandbox Code Playgroud)

但是,我收到以下错误,

TypeError: data type not understood
Run Code Online (Sandbox Code Playgroud)

这是什么意思?

Alb*_*rto 52

您可以使用以下内容:

df = pd.DataFrame({'a': pd.Series(dtype='int'),
                   'b': pd.Series(dtype='str'),
                   'c': pd.Series(dtype='float')})
Run Code Online (Sandbox Code Playgroud)

或更抽象地说:

df = pd.DataFrame({c: pd.Series(dtype=t) for c, t in {'a': 'int', 'b': 'str', 'c': 'float'}.items()})
Run Code Online (Sandbox Code Playgroud)

那么如果你打电话给 df 你有:

>>> df 
Empty DataFrame 
Columns: [a, b, c]
Index: []
Run Code Online (Sandbox Code Playgroud)

如果你检查它的类型:

>>> df.dtypes
a      int32
b     object
c    float64
dtype: object
Run Code Online (Sandbox Code Playgroud)


Sum*_*Ela 23

这是一个老问题,但我没有看到可靠的答案(尽管 @eric_g 非常接近)。

您只需要创建一个带有键值对字典的空数据框。键是您的列名,值是空数据类型。

因此,在您的示例数据集中,它将如下所示(pandas 0.25 和 python 3.7):

variables = {'contract':'',
             'state_and_county_code':'',
             'state':'',
             'county':'',
             'starting_membership':int(),
             'starting_raw_raf':float(),
             'enrollment_trend':float(),
             'projected_membership':int(),
             'projected_raf':float()}

df = pd.DataFrame(variables, index=[])
Run Code Online (Sandbox Code Playgroud)

在旧的熊猫版本中,您可能必须执行以下操作:

df = pd.DataFrame(columns=[variables])
Run Code Online (Sandbox Code Playgroud)

  • 我已经更新了上面的代码以使用最新版本的 python 和 pandas。希望能帮助到你。 (2认同)

use*_*956 15

这真的闻起来像个臭虫.

这是另一种(更简单的)解决方案.

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
Run Code Online (Sandbox Code Playgroud)


rya*_*lon 11

你可以这样

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)
Run Code Online (Sandbox Code Playgroud)


ptr*_*trj 7

只是一个评论.

您可以使用np.dtype以下方法解决类型错误:

pd.DataFrame(index = ['pbp'], columns = ['a','b'], dtype = np.dtype([('str','float')]))
Run Code Online (Sandbox Code Playgroud)

但你会得到:

NotImplementedError: compound dtypes are not implementedin the DataFrame constructor
Run Code Online (Sandbox Code Playgroud)

  • 如果它不起作用,我不知道它作为“正确答案”意味着什么。我想你是在说:“我希望这能成功”。 (3认同)
  • 这确实是正确的答案。即使修复了 TypeError,pandas 仍然懒得去实现。您甚至无法从现有的复合数据类型数据帧中复制数据类型来启动新的空数据帧,这看起来确实是一个有效的用例。 (2认同)

小智 6

我的解决方案(不设置索引)是使用列名初始化数据框并使用astype()方法指定数据类型。

df = pd.DataFrame(columns=['contract',
                     'state_and_county_code',
                     'state',
                     'county',
                     'starting_membership',
                     'starting_raw_raf',
                     'enrollment_trend',
                     'projected_membership',
                     'projected_raf'])
df = df.astype( dtype={'contract' : str, 
                 'state_and_county_code': str,
                 'state': str,
                 'county': str,
                 'starting_membership': int,
                 'starting_raw_raf': float,
                 'enrollment_trend': float,
                 'projected_membership': int,
                 'projected_raf': float})
Run Code Online (Sandbox Code Playgroud)

  • 我得出了同样的解决方案。您可以使用字典为数据框定义模式: `schema = { 'name': str, 'number': float, 'date': np.datetime64} df = pd.DataFrame(columns=schema.keys() ).astype(模式)` (5认同)

Jam*_*ore 5

遇到同样的问题后,我发现了这个问题。我更喜欢以下解决方案(Python 3)来创建一个没有 index的空 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, :]
Run Code Online (Sandbox Code Playgroud)

测试一下...

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))
Run Code Online (Sandbox Code Playgroud)

出去:

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]
Run Code Online (Sandbox Code Playgroud)

和数据类型...

print(make_empty_typed_df(dtype).dtypes)
Run Code Online (Sandbox Code Playgroud)

出去:

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
Run Code Online (Sandbox Code Playgroud)

添加索引变得棘手,因为大多数数据类型都没有真正的缺失值,因此它们最终会被强制转换为具有本机缺失值的其他类型(例如,ints 被强制转换为floats 或objects),但如果您有完整的您指定的类型的数据,然后您可以随时根据需要插入行,并且您的类型将得到尊重。这可以通过以下方式完成:

df.loc[index, :] = new_row
Run Code Online (Sandbox Code Playgroud)

同样,正如@Hun 指出的那样,这不是 Pandas 的用途。


Hun*_*Hun 1

pandas 不提供纯整数列。您可以使用浮点列并根据需要将该列转换为整数,也可以将其视为对象。您试图实现的不是 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
Run Code Online (Sandbox Code Playgroud)

您可以根据需要重新排列列顺序。但同样,这不是 pandas 应该使用的方式。

 df.dtypes
str1     object
str2     object
str2     object
int1     object
int2     object
flt1    float64
flt2    float64
dtype: object
Run Code Online (Sandbox Code Playgroud)

请注意,int 被视为对象。

  • 你到底在说什么?当然,Pandas 支持整数列。 (4认同)