我从列表列表中创建了一个DataFrame:

table = [
    ['a',  '1.2',  '4.2' ],
    ['b',  '70',   '0.03'],
    ['x',  '5',    '0'   ],
]

df = pd.DataFrame(table)

如何将列转换为特定类型?在本例中,我想将列2和列3转换为浮点数。

是否有一种方法可以在转换到DataFrame时指定类型?还是先创建DataFrame,然后循环遍历列以更改每列的类型更好?理想情况下,我希望以动态的方式进行此操作,因为可能有数百个列,而我不想确切地指定哪些列属于哪种类型。我所能保证的是每一列都包含相同类型的值。


当前回答

是否有一种方法可以在转换到DataFrame时指定类型?

是的。其他答案在创建DataFrame之后转换dtypes,但是我们可以在创建时指定类型。根据输入格式使用DataFrame.from_records或read_csv(dtype=…)。

后者有时是必要的,以避免大数据的内存错误。


1. DataFrame.from_records

从所需列类型的结构化数组创建DataFrame:

x = [['foo', '1.2', '70'], ['bar', '4.2', '5']]

df = pd.DataFrame.from_records(np.array(
    [tuple(row) for row in x], # pass a list-of-tuples (x can be a list-of-lists or 2D array)
    'object, float, int'       # define the column types
))

输出:

>>> df.dtypes
# f0     object
# f1    float64
# f2      int64
# dtype: object

2. read_csv (dtype =…)

如果从文件中读取数据,则使用read_csv的dtype参数在加载时设置列类型。

例如,这里我们读取30M行,其评级为8位整数,类型为分类:

lines = '''
foo,biography,5
bar,crime,4
baz,fantasy,3
qux,history,2
quux,horror,1
'''
columns = ['name', 'genre', 'rating']
csv = io.StringIO(lines * 6_000_000) # 30M lines

df = pd.read_csv(csv, names=columns, dtype={'rating': 'int8', 'genre': 'category'})

在这种情况下,我们在加载时将内存使用量减半:

>>> df.info(memory_usage='deep')
# memory usage: 1.8 GB
>>> pd.read_csv(io.StringIO(lines * 6_000_000)).info(memory_usage='deep')
# memory usage: 3.7 GB

这是避免大数据内存错误的一种方法。加载后并不总是可以更改dtype,因为我们可能没有足够的内存来加载默认类型的数据。

其他回答

下面是一个函数,它以一个DataFrame和一个列列表作为参数,并将列中的所有数据强制转换为数字。

# df is the DataFrame, and column_list is a list of columns as strings (e.g ["col1","col2","col3"])
# dependencies: pandas

def coerce_df_columns_to_numeric(df, column_list):
    df[column_list] = df[column_list].apply(pd.to_numeric, errors='coerce')

举个例子:

import pandas as pd

def coerce_df_columns_to_numeric(df, column_list):
    df[column_list] = df[column_list].apply(pd.to_numeric, errors='coerce')

a = [['a', '1.2', '4.2'], ['b', '70', '0.03'], ['x', '5', '0']]
df = pd.DataFrame(a, columns=['col1','col2','col3'])

coerce_df_columns_to_numeric(df, ['col2','col3'])

如果你想从字符串格式转换一列,我建议使用这段代码"

import pandas as pd
#My Test Data
data = {'Product': ['A','B', 'C','D'],
          'Price': ['210','250', '320','280']}
data


#Create Data Frame from My data df = pd.DataFrame(data)

#Convert to number
df['Price'] = pd.to_numeric(df['Price'])
df

Total = sum(df['Price'])
Total

否则,如果你要将一些列值转换为数字,我建议你先过滤你的值并保存在空数组中,然后转换为数字。我希望这段代码能解决您的问题。

当我只需要指定特定的列,并且我想要显式时,我使用(per pandas. datafframe .astype):

dataframe = dataframe.astype({'col_name_1':'int','col_name_2':'float64', etc. ...})

所以,使用原来的问题,但提供列名…

a = [['a', '1.2', '4.2'], ['b', '70', '0.03'], ['x', '5', '0']]
df = pd.DataFrame(a, columns=['col_name_1', 'col_name_2', 'col_name_3'])
df = df.astype({'col_name_2':'float64', 'col_name_3':'float64'})

我也有同样的问题。

我找不到任何令人满意的解决方案。我的解决方案是简单地将这些float转换为str并删除'。0'这边。

在我的例子中,我只在第一列上应用它:

firstCol = list(df.columns)[0]
df[firstCol] = df[firstCol].fillna('').astype(str).apply(lambda x: x.replace('.0', ''))

用这个:

a = [['a', '1.2', '4.2'], ['b', '70', '0.03'], ['x', '5', '0']]
df = pd.DataFrame(a, columns=['one', 'two', 'three'])
df

Out[16]:
  one  two three
0   a  1.2   4.2
1   b   70  0.03
2   x    5     0

df.dtypes

Out[17]:
one      object
two      object
three    object

df[['two', 'three']] = df[['two', 'three']].astype(float)

df.dtypes

Out[19]:
one       object
two      float64
three    float64