Python 在指定列类型的数据框中创建空数据框

Python 在指定列类型的数据框中创建空数据框,python,pandas,Python,Pandas,我试图创建一个带有索引的空数据框,并指定列类型。我的做法如下: df = pd.DataFrame(index=['pbp'],columns=['contract', 'state_and_county_code', 'state', 'county'

我试图创建一个带有索引的空数据框,并指定列类型。我的做法如下:

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'])
df = pd.DataFrame({'a': pd.Series([], dtype='int'),
                   'b': pd.Series([], dtype='str'),
                   'c': pd.Series([], dtype='float')})
cdt={i[0]: i[1] for i in zip(columns, dtype)}    # make column type dict
pdf=pd.DataFrame(columns=list(cdt))    # create empty dataframe
pdf=pdf.astype(cdt)                    # set desired column types
但是,我得到了以下错误:

TypeError: data type not understood

这意味着什么?

熊猫不提供纯整数列。您可以使用float列并根据需要将该列转换为整数,也可以将其视为对象。你试图实现的不是熊猫应该被使用的方式。但是,如果您真的想要这样做,您可以通过这样做绕过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
您可以根据需要重新排列列顺序。但同样,这不是熊猫应该被使用的方式

 df.dtypes
str1     object
str2     object
str2     object
int1     object
int2     object
flt1    float64
flt2    float64
dtype: object
请注意,int被视为对象。

只是一个备注

您可以使用
np.dtype
绕过类型错误:

pd.DataFrame(index = ['pbp'], columns = ['a','b'], dtype = np.dtype([('str','float')]))
但你得到的是:

NotImplementedError: compound dtypes are not implementedin the DataFrame constructor

我在遇到同样的问题后发现了这个问题。我更喜欢下面的解决方案(Python3)来创建没有索引的空数据帧

测试这个

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))
Out:

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]
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
而数据类型

print(make_empty_typed_df(dtype).dtypes)
Out:

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]
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
s被转换为
float
s或
object
s),但是如果您拥有指定类型的完整数据,然后,您可以随时根据需要插入行,您的类型将得到尊重。这可以通过以下方式实现:

df.loc[index, :] = new_row

同样,正如@Hun所指出的,这不是熊猫的使用方式。

您可以通过将字典传递到数据帧构造函数来实现这一点:

 df.dtypes
str1     object
str2     object
str2     object
int1     object
int2     object
flt1    float64
flt2    float64
dtype: object
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
使用数据类型:

contract                 object
projected_membership    float64
starting_membership       int64
也就是说,有两件事需要注意:

1)
str
实际上不是数据帧列可以处理的类型;相反,它返回到一般情况下的
对象
。它仍然可以正常工作


2) 您为什么不在
开始加入
下看到
NaN
?嗯,
NaN
仅为浮点数定义;整数没有“None”值,因此它将
np.NaN
强制转换为整数。如果您想要一个不同的默认值,您可以在
np.full
调用中更改它。

这听起来真像个bug

这里有另一个(更简单的)解决方案

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

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

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

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

在旧版本中,可能需要执行以下操作:

df = pd.DataFrame(columns=[variables])

你可以这样做

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)

我发现对我来说,最简单的解决方法是为每个列连接一个空序列列表:

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
将熊猫作为pd导入
列=[“合同”,
“州和县代码”,
“国家”,
"县",,
"入会",,
“启动raf”,
“入学趋势”,
"预计的大学会籍",,
“预计的皇家空军”]
数据类型=['str','str','str','str','int','float','float','int','float']
df=pd.concat([pd.Series(name=col,dtype=dt)表示col,dt在zip中(columns,dtype)],axis=1)
df.info()
# 
#索引:0个条目
#数据列(共9列):
#协定0非空对象
#州和县代码0非空对象
#状态0为非空对象
#县0非空对象
#正在启动\u成员身份0非空int32
#正在启动\u原始\u raf 0非空浮点64
#注册趋势0非空浮点64
#计划的\u成员身份0非空int32
#投影的_raf 0非空浮点64
#数据类型:float64(3)、int32(2)、object(4)
#内存使用:0.0+字节
我的解决方案(不设置索引)是使用列名初始化数据帧,并使用
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})

您可以使用以下选项:

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'])
df = pd.DataFrame({'a': pd.Series([], dtype='int'),
                   'b': pd.Series([], dtype='str'),
                   'c': pd.Series([], dtype='float')})
cdt={i[0]: i[1] for i in zip(columns, dtype)}    # make column type dict
pdf=pd.DataFrame(columns=list(cdt))    # create empty dataframe
pdf=pdf.astype(cdt)                    # set desired column types
那么如果你打电话给df,你有

>>> df 
Empty DataFrame 
Columns: [a, b, c]
Index: []
如果你检查它的类型

>>> df.dtypes
a      int32
b     object
c    float64
dtype: object

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

我认为这是完美的

import pandas as pd

c1 = pd.Series(data=None, dtype='string', name='c1')
c2 = pd.Series(data=None, dtype='bool', name='c2')
c3 = pd.Series(data=None, dtype='float', name='c3')
c4 = pd.Series(data=None, dtype='int', name='c4')

df = pd.concat([c1, c2, c3, c4], axis=1)

df.info('verbose')
我们将列创建为序列,并为它们提供正确的数据类型,然后将de Series合并到一个数据帧中,就是这样

我们有数据类型的数据帧构造函数

<class 'pandas.core.frame.DataFrame'>
Index: 0 entries
Data columns (total 4 columns):
 #   Column  Non-Null Count  Dtype  
---  ------  --------------  -----  
 0   c1      0 non-null      string 
 1   c2      0 non-null      bool   
 2   c3      0 non-null      float64
 3   c4      0 non-null      int32  
dtypes: bool(1), float64(1), int32(1), string(1)
memory usage: 0.0+ bytes

索引:0个条目
数据列(共4列):
#列非空计数数据类型
---  ------  --------------  -----  
0 c1 0非空字符串
1 c2 0非空布尔值
2 c3 0非空浮点64
3 c4 0非空int32
数据类型:bool(1)、float64(1)、int32(1)、string(1)
内存使用:0.0+字节

从examle中获取列表列和数据类型,您可以执行以下操作:

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'])
df = pd.DataFrame({'a': pd.Series([], dtype='int'),
                   'b': pd.Series([], dtype='str'),
                   'c': pd.Series([], dtype='float')})
cdt={i[0]: i[1] for i in zip(columns, dtype)}    # make column type dict
pdf=pd.DataFrame(columns=list(cdt))    # create empty dataframe
pdf=pdf.astype(cdt)                    # set desired column types

DataFrame doc说构造函数调用中只允许一个数据类型。

我认为您不能用这种方式指定数据类型,您可以传递一个类型,例如
str
,但不能传递字符串列表。分配列值时将推断数据类型。我认为没有必要具体说明all@EdChum根据,我想知道为什么构造器不允许。。。从一开始就用类型创建一个空的数据帧来进行分配不是更有效吗?你到底在说什么?当然,Pandas支持整数列。不过,在没有数据的情况下传递
dtype=int
似乎确实存在问题。这看起来绝对像是一个bug——这仍然是最新版本中的行为。你提交了吗?它的预期行为,它在警告中列出。这是因为
int
没有
nan
。您可以在@VictorUriarte上阅读更多关于它的信息,它没有解释为什么在constr中不能指定int列