如何通过pandas读取类似鸢尾花数据集格式的csv文件?
发布于 作者:苏南大叔 来源:程序如此灵动~本文还是继续描述sklearn
加载鸢尾花数据集的故事,首先,需要明确的是:读取数据集的目的是为了机器学习。所以,本文的需求输入是.csv
文件,输出是X
和y
两个变量。这两个变量的格式,可以是ndarray
,还可以是DataFrame
。并不会影响机器学习的后续代码。
大家好,这里是苏南大叔的“程序如此灵动”博客,记录计算机代码的各种故事。本文描述的是:为sklearn
的机器学习各种算法,提供来自.csv
文件的X
和y
两个变量数据。龙套演员还是曾经分析过的鸢尾花数据集,因为本文的需要,这里就假设鸢尾花数据集是个外部的.csv
文件。测试环境:win10
,python@3.11.0
,pip@23.0.1
,scikit-learn@1.2.2
。
当然确实可以使用sklearn
的load_iris()
函数直接加载,但是本文侧重于加载【类似于】iris.csv
的数据集,鸢尾花数据集仅仅是个龙套的概念角色。
准备样本数据.csv
文件
这个.csv
文件其实没有太多的要求的,只要读取之后,能分出来X
和y
数据即可,然后就可以用于机器学习的代码里面了。可以参考鸢尾花的标准csv
文件:
从前面苏南大叔对鸢尾花数据集的介绍中,可以得到一些线索。标准的鸢尾花数据集(比如sklearn
中的iris.csv
)的第一行数据,并不是传统意义上的表头。而是个奇怪的值,分别表示:
- 150条可以数据。
- 前四个字段是
X
(剩下的最后一个字段是y
)。 - 最后一个字段的“0/1/2”所具体表示的对应种类“setosa/versicolor/virginica”。
那么,对于一个非官方的数据集.csv
文件来说,重点就是:是不是存在着表头。这个内在的数据因素,决定了读取.csv
文件的方法参数。如果存在表头,倒也不必模仿鸢尾花数据集的表头写法,因为这并不是重点。
关于这个鸢尾花数据集的详细描述,可以参考:
读取类似于鸢尾花的.csv
文件
本段内容中,使用哪种方式读取csv
文件,主要取决于csv
文件自身的内容。所以,请自行分辨。
对于本文需求,苏南大叔认为:
- 对于一个并不重要的表头,只会影响读取到的数据集的准确性。表头里面具体写了些什么,也许并不重要。
- 使用什么
python
库来读取csv
文件,也并不重要。
当然,本文采用了pandas
来读取数据集,目标文件名是iris.csv
。
没有表头的读取方式举例:
import pandas as pd
data = pd.read_csv("iris.csv")
有表头的读取方式举例【重点】【常用】:
import pandas as pd
data = pd.read_csv("iris.csv",skiprows=1)
跳过无用数据的方式(跳过第一行第二行和尾行):
import pandas as pd
data = pd.read_csv("iris.csv",skiprows=[1,2],skipfooter=1,engine='python')
使用skipfooter
参数的话,就强制设置参数engine='python'
。
自定义表头:
import pandas as pd
data = pd.read_csv("iris.csv",names=["a","b","c","d","label"])
所以,对于类似iris.csv
的数据集来说,正确的参数设置应该是:
import pandas as pd
data = pd.read_csv("iris.csv",skiprows=1,names=["a","b","c","d","label"]) # 推荐
所以正确的做法是,“使用一个错误的表头” 或者 “跳过第一条数据,同时设置一个新的表头”。仅仅使用跳过表头的设置是不行的,第二行数据会变成新的错误表头。
也可以直接从远程读取csv
数据,代码不变:
import pandas as pd
data_url = "http://download.tensorflow.org/data/iris_training.csv"
data = pd.read_csv(data_url, header=0)
# print(data.head(1))
# print(data.tail(2))
当然,从网络上读取数据文件,就要承担网络不稳定的风险。
iloc()
划分X
和y
【推荐】
这里使用pandas
来读取csv
文件,得到的是个DataFrame
格式的数据,所以苏南大叔使用iloc()
来做进一步的数据处理。
对于iloc(row_expression,column_expression)
来说,
- 第一个参数是行表达式,应该都是
:
,表示要取所有的行。 - 第二个参数就是要看具体的数据集的情况了,看情况来分析。
对于标准的鸢尾花数据集来说,
X = data.iloc[:,:-1]
y = data.iloc[:,-1:]
X
表示的是样本数据,对应的就是前四个字段,就是:-1
,或者0:4
,就是标准Bunch
类型中的iris["data"]
。y
表示的是结果标签,对应的就是最后一个字段,也就是-1:
,或者说4:
。
a:b,包含a,不包含b。a从0开始计数。
loc()
划分X
和y
对于其它的自定义数据集来说,可以确定的是,上述结论,极有可能是不合适的。所以,也可以使用loc()
用列的表头来获取,比如:
X = data.loc[:,"a":"d"]
y = data.loc[:,"label":]
设定修改数据类型(无关紧要)
默认的数据类型是DataFrame
。
X = data.iloc[:,:-1]
y = data.iloc[:,-1:]
print(type(X),type(y))
输出:
<class 'pandas.core.frame.DataFrame'> <class 'pandas.core.frame.DataFrame'>
也可以通过.values
或者强制类型转换操作,变成ndarray
类型。
import numpy as np
X = data.iloc[:,:-1].values
y = np.array(data.iloc[:,-1:])
print(type(X),type(y))
输出:
<class 'numpy.ndarray'> <class 'numpy.ndarray'>
对于机器学习sklearn
来说,无论是DataFrame
还是ndarray
都是可以训练或识别的。所以,是否转化格式并不重要。
为机器学习做进一步加工准备
拿到机器学习所需要的X
和y
之后,一般来说,X
是有很多特征数据的,所以是个二维数组。而y
则是一个结论性质的数据,通常来说是应该是个一维的。那么,如果在传入机器学习模型的时候,看到了如下类似错误提示信息:
D:\Program Files\Python368\lib\site-packages\sklearn\utils\validation.py:63: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel().
return f(*args, **kwargs)
那么,多半是因为y
值的问题,需要把y
扁平化处理,就是变成一维数组,一列数据变成一行数据。例如:
X = data.iloc[:, :-1].values
y = data.iloc[:, -1:].values.flatten()
当然,这里是个警告信息,大概率是不会影响模型预测的结果的。
如果是使用sklearn
的datasets.load_iris()
(无任何参数版本)拿到的X
和y
。则不需要做进一步的扁平化处理。因为这个时候,X
就是个多维ndarray
,而y
就是个已经扁平化处理过的一维ndarray
。
from sklearn import datasets
iris = datasets.load_iris()
X = iris.data # 默认已经是ndarray了
y = iris.target # 默认已经是一维ndarray了
参考文献
- https://newsn.net/say/iris.html
- https://newsn.net/say/sklearn.html
- https://newsn.net/say/dataframe-loc.html
总结
在本文中,主要是以鸢尾花数据集iris.csv
作为龙套演员,对其可能推断出来的数据进行了描述。必须采集到X
和y
的信息,然后为后续的机器学习做准备。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。