pandas:多列的 to_numeric
Posted
技术标签:
【中文标题】pandas:多列的 to_numeric【英文标题】:pandas: to_numeric for multiple columns 【发布时间】:2016-08-17 06:45:18 【问题描述】:我正在使用以下df:
c.sort_values('2005', ascending=False).head(3)
GeoName ComponentName IndustryId IndustryClassification Description 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014
37926 Alabama Real GDP by state 9 213 Support activities for mining 99 98 117 117 115 87 96 95 103 102 (NA)
37951 Alabama Real GDP by state 34 42 Wholesale trade 9898 10613 10952 11034 11075 9722 9765 9703 9600 9884 10199
37932 Alabama Real GDP by state 15 327 Nonmetallic mineral products manufacturing 980 968 940 1084 861 724 714 701 589 641 (NA)
我想对所有年份强制使用数字:
c['2014'] = pd.to_numeric(c['2014'], errors='coerce')
有没有简单的方法可以做到这一点,还是我必须全部输入?
【问题讨论】:
【参考方案1】:更新:之后您不需要转换您的值,您可以在读取 CSV 时即时进行:
In [165]: df=pd.read_csv(url, index_col=0, na_values=['(NA)']).fillna(0)
In [166]: df.dtypes
Out[166]:
GeoName object
ComponentName object
IndustryId int64
IndustryClassification object
Description object
2004 int64
2005 int64
2006 int64
2007 int64
2008 int64
2009 int64
2010 int64
2011 int64
2012 int64
2013 int64
2014 float64
dtype: object
如果您需要将多列转换为数字 dtype - 使用以下技术:
示例源 DF:
In [271]: df
Out[271]:
id a b c d e f
0 id_3 AAA 6 3 5 8 1
1 id_9 3 7 5 7 3 BBB
2 id_7 4 2 3 5 4 2
3 id_0 7 3 5 7 9 4
4 id_0 2 4 6 4 0 2
In [272]: df.dtypes
Out[272]:
id object
a object
b int64
c int64
d int64
e int64
f object
dtype: object
将选定的列转换为数字类型:
In [273]: cols = df.columns.drop('id')
In [274]: df[cols] = df[cols].apply(pd.to_numeric, errors='coerce')
In [275]: df
Out[275]:
id a b c d e f
0 id_3 NaN 6 3 5 8 1.0
1 id_9 3.0 7 5 7 3 NaN
2 id_7 4.0 2 3 5 4 2.0
3 id_0 7.0 3 5 7 9 4.0
4 id_0 2.0 4 6 4 0 2.0
In [276]: df.dtypes
Out[276]:
id object
a float64
b int64
c int64
d int64
e int64
f float64
dtype: object
PS 如果您想选择所有 string
(object
) 列,请使用以下简单技巧:
cols = df.columns[df.dtypes.eq('object')]
【讨论】:
感谢 MaxU,您的两个回答 :) @MichaelPerdue,很高兴为您提供帮助 :) 为了完整性:您还可以在初始化数据帧时即时进行转换,例如:pd.DataFrame(datalist, dtype=float),它将在可能的情况下将所有字段转换为浮点数(并且其他保持不变) 当我这样做时,为什么有些行变成了 NaN? @h_musk,请查看提供的解决方案中的示例。所有不能转换为数值的值都会变成 NaN。【参考方案2】:另一种方法是使用apply
,一个班轮:
cols = ['col1', 'col2', 'col3']
data[cols] = data[cols].apply(pd.to_numeric, errors='coerce', axis=1)
【讨论】:
如果我们想要转换为分类而不是数字,该怎么办?【参考方案3】:你可以使用:
print df.columns[5:]
Index([u'2004', u'2005', u'2006', u'2007', u'2008', u'2009', u'2010', u'2011',
u'2012', u'2013', u'2014'],
dtype='object')
for col in df.columns[5:]:
df[col] = pd.to_numeric(df[col], errors='coerce')
print df
GeoName ComponentName IndustryId IndustryClassification \
37926 Alabama Real GDP by state 9 213
37951 Alabama Real GDP by state 34 42
37932 Alabama Real GDP by state 15 327
Description 2004 2005 2006 2007 \
37926 Support activities for mining 99 98 117 117
37951 Wholesale trade 9898 10613 10952 11034
37932 Nonmetallic mineral products manufacturing 980 968 940 1084
2008 2009 2010 2011 2012 2013 2014
37926 115 87 96 95 103 102 NaN
37951 11075 9722 9765 9703 9600 9884 10199.0
37932 861 724 714 701 589 641 NaN
filter
的另一个解决方案:
print df.filter(like='20')
2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014
37926 99 98 117 117 115 87 96 95 103 102 (NA)
37951 9898 10613 10952 11034 11075 9722 9765 9703 9600 9884 10199
37932 980 968 940 1084 861 724 714 701 589 641 (NA)
for col in df.filter(like='20').columns:
df[col] = pd.to_numeric(df[col], errors='coerce')
print df
GeoName ComponentName IndustryId IndustryClassification \
37926 Alabama Real GDP by state 9 213
37951 Alabama Real GDP by state 34 42
37932 Alabama Real GDP by state 15 327
Description 2004 2005 2006 2007 \
37926 Support activities for mining 99 98 117 117
37951 Wholesale trade 9898 10613 10952 11034
37932 Nonmetallic mineral products manufacturing 980 968 940 1084
2008 2009 2010 2011 2012 2013 2014
37926 115 87 96 95 103 102 NaN
37951 11075 9722 9765 9703 9600 9884 10199.0
37932 861 724 714 701 589 641 NaN
【讨论】:
很高兴能帮到您!祝你好运!【参考方案4】:df[cols] = pd.to_numeric(df[cols].stack(), errors='coerce').unstack()
【讨论】:
为我工作。一种将多列转换为数字的更简洁的方法。 正如@Blessy 所说。更清洁和简单,这适用于 nan 值。【参考方案5】:如果您正在寻找一系列列,您可以试试这个:
df.iloc[7:] = df.iloc[7:].astype(float)
上面的示例将类型转换为浮点数,因为所有列都从第 7 列开始到末尾。你当然可以使用不同的类型或不同的范围。
我认为当您需要转换大量列和大量行时,这很有用。它不会让您自己遍历每一行 - 我相信 numpy 会更有效地完成。
这仅在您知道所有必需的列仅包含数字时才有用 - 它不会将“坏值”(如字符串)更改为 NaN。
【讨论】:
对我来说,它不是从第 7 列开始,而是从第一列开始。 我也是。它从第一列开始astype(float)
不能单独替换 pd.to_numeric
与 errors='coerce'
这是问题的一部分。将触发异常。【参考方案6】:
df.loc[:,'col':] = df.loc[:,'col':].apply(pd.to_numeric, errors = 'coerce')
【讨论】:
虽然此代码可能会为问题提供解决方案,但最好添加有关其工作原理/方式的上下文。这可以帮助未来的用户学习并最终将这些知识应用到他们自己的代码中。解释代码时,您也可能会得到用户的积极反馈/赞成。 我实际上是在这里结束的,因为我正是这样做的,它不适用于 df.loc以上是关于pandas:多列的 to_numeric的主要内容,如果未能解决你的问题,请参考以下文章