Change data type of columns in Pandas
我想将一个表(表示为列表列表)转换为熊猫数据帧。作为一个非常简单的例子:
1 2 | a = [['a', '1.2', '4.2'], ['b', '70', '0.03'], ['x', '5', '0']] df = pd.DataFrame(a) |
将列转换为适当的类型的最佳方法是什么,在这种情况下,将列2和3转换为float?转换为数据帧时是否有指定类型的方法?还是先创建数据帧,然后循环遍历列以更改每列的类型更好?理想情况下,我希望以动态方式执行此操作,因为可能有数百个列,我不想确切地指定哪些列属于哪种类型。我能保证的就是每列都包含相同类型的值。
您有三个转换熊猫类型的主要选项:好的。
请继续阅读,了解这些方法的更详细解释和用法。好的。1。
将数据帧的一列或多列转换为数值的最佳方法是使用
此函数将尝试根据需要将非数字对象(如字符串)更改为整数或浮点数。好的。基本用法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | >>> s = pd.Series(["8", 6,"7.5", 3,"0.9"]) # mixed string and numeric values >>> s 0 8 1 6 2 7.5 3 3 4 0.9 dtype: object >>> pd.to_numeric(s) # convert everything to float values 0 8.0 1 6.0 2 7.5 3 3.0 4 0.9 dtype: float64 |
如您所见,将返回一个新的序列。请记住将此输出分配给变量或列名以继续使用它:好的。
1 2 3 4 5 | # convert Series my_series = pd.to_numeric(my_series) # convert column"a" of a DataFrame df["a"] = pd.to_numeric(df["a"]) |
您还可以使用它通过
1 2 3 4 5 | # convert all columns of DataFrame df = df.apply(pd.to_numeric) # convert all columns of DataFrame # convert just columns"a" and"b" df[["a","b"]] = df[["a","b"]].apply(pd.to_numeric) |
只要你的值都能被转换,这可能就是你所需要的。好的。错误处理
但是如果一些值不能转换成数字类型呢?好的。
下面是一个使用一系列字符串
1 2 3 4 5 6 7 8 | >>> s = pd.Series(['1', '2', '4.7', 'pandas', '10']) >>> s 0 1 1 2 2 4.7 3 pandas 4 10 dtype: object |
如果无法转换值,则默认行为是提升。在这种情况下,它无法处理字符串"pandas":好的。
1 2 | >>> pd.to_numeric(s) # or pd.to_numeric(s, errors='raise') ValueError: Unable to parse string |
我们可能希望"pandas"被视为丢失/错误的数值,而不是失败。我们可以使用
1 2 3 4 5 6 7 | >>> pd.to_numeric(s, errors='coerce') 0 1.0 1 2.0 2 4.7 3 NaN 4 10.0 dtype: float64 |
1 2 | >>> pd.to_numeric(s, errors='ignore') # the original Series is returned untouched |
最后一个选项在您希望转换整个数据帧时特别有用,但不知道哪一列可以可靠地转换为数字类型。在这种情况下,只需写:好的。
1 | df.apply(pd.to_numeric, errors='ignore') |
该函数将应用于数据帧的每一列。可以转换为数字类型的列将被转换,而不能转换的列(例如,它们包含非数字字符串或日期)将被单独保留。好的。向下转型
默认情况下,使用
这通常是您想要的,但是如果您想要保存一些内存并使用更紧凑的数据类型,比如
1 2 3 4 5 6 | >>> s = pd.Series([1, 2, -7]) >>> s 0 1 1 2 2 -7 dtype: int64 |
向下转换为"integer"时使用可以保存值的最小可能整数:好的。
1 2 3 4 5 | >>> pd.to_numeric(s, downcast='integer') 0 1 1 2 2 -7 dtype: int8 |
向下转换为"float"类似地选择一个小于正常的浮动类型:好的。
1 2 3 4 5 | >>> pd.to_numeric(s, downcast='float') 0 1.0 1 2.0 2 -7.0 dtype: float32 |
2。
只需选择一个类型:您可以使用numpy数据类型(例如
调用要转换的对象的方法,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | # convert all DataFrame columns to the int64 dtype df = df.astype(int) # convert column"a" to int64 dtype and"b" to complex type df = df.astype({"a": int,"b": complex}) # convert Series to float16 type s = s.astype(np.float16) # convert Series to Python strings s = s.astype(str) # convert Series to categorical type - see docs for more details s = s.astype('category') |
注意,我说的是"尝试"——如果
从熊猫0.20.0开始,这个误差可以通过传递
1 2 3 4 5 6 | >>> s = pd.Series([1, 2, -7]) >>> s 0 1 1 2 2 -7 dtype: int64 |
这些是小整数,那么转换为无符号8位类型以节省内存如何?好的。
1 2 3 4 5 | >>> s.astype(np.uint8) 0 1 1 2 2 249 dtype: uint8 |
转换成功了,但是-7被包裹成了249(即28-7)!好的。
尝试使用
panda的0.21.0版引入了方法
例如,这里有一个具有两列对象类型的数据框。一个包含实际整数,另一个包含表示整数的字符串:好的。
1 2 3 4 5 | >>> df = pd.DataFrame({'a': [7, 1, 5], 'b': ['3','2','1']}, dtype='object') >>> df.dtypes a object b object dtype: object |
使用
1 2 3 4 5 | >>> df = df.infer_objects() >>> df.dtypes a int64 b object dtype: object |
列"b"被单独保留,因为它的值是字符串,而不是整数。如果要尝试强制将两列转换为整数类型,可以使用
这个怎么样?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 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 |
下面的代码将更改列的数据类型。
1 | df[['col.name1', 'col.name2'...]] = df[['col.name1', 'col.name2'..]].astype('data_type') |
代替数据类型,你可以给出你的数据类型。你想要什么,比如str,float,int等等。
这是一个函数,它将数据框和列列表作为参数,并将列中的所有数据强制为数字。
1 2 3 4 5 | # 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') |
因此,举个例子:
1 2 3 4 5 6 7 8 9 | 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']) |
如何创建两个数据帧,每个数据帧的列都有不同的数据类型,然后将它们附加在一起?
1 2 | d1 = pd.DataFrame(columns=[ 'float_column' ], dtype=float) d1 = d1.append(pd.DataFrame(columns=[ 'string_column' ], dtype=str)) |
结果
1 2 3 4 5 | In[8}: d1.dtypes Out[8]: float_column float64 string_column object dtype: object |
创建数据帧后,可以在第一列中用浮点变量填充它,在第二列中用字符串(或任何您需要的数据类型)填充它。
当我只需要指定特定的列,并且希望明确时,我使用了(每个文档位置):
1 | dataframe = dataframe.astype({'col_name_1':'int','col_name_2':'float64', etc. ...}) |
所以,使用原来的问题,但提供列名…
1 2 3 | 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'}) |
我以为我有同样的问题,但实际上我有一个微小的差别,这使得问题更容易解决。对于关注这个问题的其他人来说,值得检查输入列表的格式。在我的例子中,数字最初是浮动的,而不是像问题中那样的字符串:
1 | a = [['a', 1.2, 4.2], ['b', 70, 0.03], ['x', 5, 0]] |
但是,在创建数据帧之前处理列表太多,我会丢失类型,所有内容都变成字符串。
通过numpy数组创建数据帧
1 2 3 4 5 6 7 8 9 10 11 | df = pd.DataFrame(np.array(a)) df Out[5]: 0 1 2 0 a 1.2 4.2 1 b 70 0.03 2 x 5 0 df[1].dtype Out[7]: dtype('O') |
给出与问题中相同的数据帧,其中第1列和第2列中的条目被视为字符串。然而做
1 2 3 4 5 6 7 8 9 10 11 | df = pd.DataFrame(a) df Out[10]: 0 1 2 0 a 1.2 4.20 1 b 70.0 0.03 2 x 5.0 0.00 df[1].dtype Out[11]: dtype('float64') |
实际给出的数据帧中列的格式是否正确