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

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

df = pd.DataFrame(table)

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

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


当前回答

我也有同样的问题。

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

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

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

其他回答

如果你有各种各样的对象列,比如74个对象列和2个Int列,其中每个值都有字母表示单位:

import pandas as pd 
import numpy as np

dataurl = 'https://raw.githubusercontent.com/RubenGavidia/Pandas_Portfolio.py/main/Wes_Mckinney.py/nutrition.csv'
nutrition = pd.read_csv(dataurl,index_col=[0])
nutrition.head(3)

输出:

    name    serving_size    calories    total_fat    saturated_fat    cholesterol    sodium    choline    folate    folic_acid    ...    fat    saturated_fatty_acids    monounsaturated_fatty_acids    polyunsaturated_fatty_acids    fatty_acids_total_trans    alcohol    ash    caffeine    theobromine    water
0    Cornstarch    100 g    381    0.1g    NaN    0    9.00 mg    0.4 mg    0.00 mcg    0.00 mcg    ...    0.05 g    0.009 g    0.016 g    0.025 g    0.00 mg    0.0 g    0.09 g    0.00 mg    0.00 mg    8.32 g
1    Nuts, pecans    100 g    691    72g    6.2g    0    0.00 mg    40.5 mg    22.00 mcg    0.00 mcg    ...    71.97 g    6.180 g    40.801 g    21.614 g    0.00 mg    0.0 g    1.49 g    0.00 mg    0.00 mg    3.52 g
2    Eggplant, raw    100 g    25    0.2g    NaN    0    2.00 mg    6.9 mg    22.00 mcg    0.00 mcg    ...    0.18 g    0.034 g    0.016 g    0.076 g    0.00 mg    0.0 g    0.66 g    0.00 mg    0.00 mg    92.30 g
3 rows × 76 columns

nutrition.dtypes
name             object
serving_size     object
calories          int64
total_fat        object
saturated_fat    object
                  ...
alcohol          object
ash              object
caffeine         object
theobromine      object
water            object
Length: 76, dtype: object

nutrition.dtypes.value_counts()
object    74
int64      2
dtype: int64

将所有列转换为数值的一个好方法是使用正则表达式来替换单位,并使用astype(float)来更改列数据类型为float:

nutrition.index = pd.RangeIndex(start = 0, stop = 8789, step= 1)
nutrition.set_index('name',inplace = True)
nutrition.replace('[a-zA-Z]','', regex= True, inplace=True)
nutrition=nutrition.astype(float)
nutrition.head(3)

输出:

serving_size    calories    total_fat    saturated_fat    cholesterol    sodium    choline    folate    folic_acid    niacin    ...    fat    saturated_fatty_acids    monounsaturated_fatty_acids    polyunsaturated_fatty_acids    fatty_acids_total_trans    alcohol    ash    caffeine    theobromine    water
name
Cornstarch    100.0    381.0    0.1    NaN    0.0    9.0    0.4    0.0    0.0    0.000    ...    0.05    0.009    0.016    0.025    0.0    0.0    0.09    0.0    0.0    8.32
Nuts, pecans    100.0    691.0    72.0    6.2    0.0    0.0    40.5    22.0    0.0    1.167    ...    71.97    6.180    40.801    21.614    0.0    0.0    1.49    0.0    0.0    3.52
Eggplant, raw    100.0    25.0    0.2    NaN    0.0    2.0    6.9    22.0    0.0    0.649    ...    0.18    0.034    0.016    0.076    0.0    0.0    0.66    0.0    0.0    92.30
3 rows × 75 columns

nutrition.dtypes
serving_size     float64
calories         float64
total_fat        float64
saturated_fat    float64
cholesterol      float64
                  ...
alcohol          float64
ash              float64
caffeine         float64
theobromine      float64
water            float64
Length: 75, dtype: object

nutrition.dtypes.value_counts()
float64    75
dtype: int64

现在数据集是干净的,你只能用regex和astype()对这个数据帧进行数值操作。

如果你想收集单位,并粘贴在标题如胆固醇,你可以使用下面的代码:

nutrition.index = pd.RangeIndex(start = 0, stop = 8789, step= 1)
nutrition.set_index('name',inplace = True)
nutrition.astype(str).replace('[^a-zA-Z]','', regex= True)
units = nutrition.astype(str).replace('[^a-zA-Z]','', regex= True)
units = units.mode()
units = units.replace('', np.nan).dropna(axis=1)
mapper = { k: k + "_" + units[k].at[0] for k in units}
nutrition.rename(columns=mapper, inplace=True)
nutrition.replace('[a-zA-Z]','', regex= True, inplace=True)
nutrition=nutrition.astype(float)

创建两个数据框架,每个数据框架的列都有不同的数据类型,然后将它们附加在一起:

d1 = pd.DataFrame(columns=[ 'float_column' ], dtype=float)
d1 = d1.append(pd.DataFrame(columns=[ 'string_column' ], dtype=str))

结果

In[8}:  d1.dtypes
Out[8]:
float_column     float64
string_column     object
dtype: object

创建数据帧后,可以在第一列中使用浮点变量填充它,在第二列中使用字符串(或任何您想要的数据类型)填充它。

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

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

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

用这个:

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

从pandas 1.0.0开始,我们有pandas. dataframe .convert_dtypes。您甚至可以控制要转换的类型!

In [40]: df = pd.DataFrame(
    ...:     {
    ...:         "a": pd.Series([1, 2, 3], dtype=np.dtype("int32")),
    ...:         "b": pd.Series(["x", "y", "z"], dtype=np.dtype("O")),
    ...:         "c": pd.Series([True, False, np.nan], dtype=np.dtype("O")),
    ...:         "d": pd.Series(["h", "i", np.nan], dtype=np.dtype("O")),
    ...:         "e": pd.Series([10, np.nan, 20], dtype=np.dtype("float")),
    ...:         "f": pd.Series([np.nan, 100.5, 200], dtype=np.dtype("float")),
    ...:     }
    ...: )

In [41]: dff = df.copy()

In [42]: df 
Out[42]: 
   a  b      c    d     e      f
0  1  x   True    h  10.0    NaN
1  2  y  False    i   NaN  100.5
2  3  z    NaN  NaN  20.0  200.0

In [43]: df.dtypes
Out[43]: 
a      int32
b     object
c     object
d     object
e    float64
f    float64
dtype: object

In [44]: df = df.convert_dtypes()

In [45]: df.dtypes
Out[45]: 
a      Int32
b     string
c    boolean
d     string
e      Int64
f    float64
dtype: object

In [46]: dff = dff.convert_dtypes(convert_boolean = False)

In [47]: dff.dtypes
Out[47]: 
a      Int32
b     string
c     object
d     string
e      Int64
f    float64
dtype: object