如何通过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的信息,然后为后续的机器学习做准备。