在本教程中,我们将重点关注read_csv
函数,它允许我们读取 CSV 文件并将其转换为Pandas数据框。
The read_csv
function 不仅仅是一个 CSV 文件加载工具。它配备了大量参数来处理 CSV 文件中可能出现的各种情况。
什么是 Pandas read_csv?
无论是处理跳过不必要的行、获取特定列、定义列数据类型、解析日期列、处理空行,甚至处理空值,read_csv
已满足您的需求。
您将学习如何以不同的方式读取不同的 CSV 文件,所以让我们开始吧。
指定数据源
pandas 的第一个参数read_csv
是我们要读取的 CSV 文件的字符串路径。该字符串可以是 URL、文件路径或表示数据源的任何有效字符串名称。
让我们从 CSV 文件加载一些电信公司数据。
df = pd.read_csv('telecom_data.csv')
print(df.head())
Output:
CustomerID Gender SeniorCitizen Partner Dependents tenure PhoneService
0 7590 Male 0 No No 1 Yes
1 5575 Male 0 No No 34 No
2 3668 Female 0 No No 2 Yes
3 7795 Female 0 No No 45 No
4 9237 Female 0 No No 2 Yes
在这里,我们使用read_csv
pandas 的函数从我们的 CSV 文件加载数据,然后我们使用以下命令打印前 5 行.head()
功能。
自定义分隔符
有时,CSV 文件中的数据可能不会用逗号(默认分隔符)分隔。 “sep”参数允许您指定分隔数据的分隔符。
我将示例文件转换为制表符分隔文件,以演示如何处理具有不同分隔符的文件,它如下所示:
CustomerID Gender SeniorCitizen Partner Dependents tenure PhoneService
7590 Male 0 No No 1 Yes
5575 Male 0 No No 34 No
3668 Female 0 No No 2 Yes
7795 Female 0 No No 45 No
9237 Female 0 No No 2 Yes
现在,让我们阅读使用read_csv
:
df = pd.read_csv('telecom_data.tsv', sep='\t')
print(df.head())
Output:
CustomerID Gender SeniorCitizen Partner Dependents tenure PhoneService
0 7590 Male 0 No No 1 Yes
1 5575 Male 0 No No 34 No
2 3668 Female 0 No No 2 Yes
3 7795 Female 0 No No 45 No
4 9237 Female 0 No No 2 Yes
在这种情况下,“\t”(制表符)用作分隔符。如果分隔符未正确指定,pandas 会将整行解释为单列。
默认情况下,pandas 从文件的第一行推断列名。但有时,您可能想使用不同的行作为标题。您可以通过设置“header”参数来实现此目的。
df = pd.read_csv('telecom_data.csv', header=1)
print(df.head())
Output:
7590 Male 0 No No 1 Yes
0 5575 Male 0 No No 34 No
1 3668 Female 0 No No 2 Yes
2 7795 Female 0 No No 45 No
3 9237 Female 0 No No 2 Yes
4 9305 Male 0 Yes No 8 Yes
现在,pandas 将从第二行(索引从 0 开始)而不是第一行推断列名称。
对于具有多索引列名的文件,您可以将列表传递给 header 参数以指定要使用的行。
data = StringIO("Header1,Header2,Header3\nSubHeader1,SubHeader2,SubHeader3\nA,B,C\n1,2,3")
df = pd.read_csv(data, header=[0,1])
print(df)
Output:
Header1 SubHeader1 Header2 SubHeader2 Header3 SubHeader3
0 A B C 1 2 3
注意:如果第一行有数据,请记住设置 header=0,否则,它将被视为列名。
设置DataFrame索引
‘index_col’参数指定用作行标签的列数据框。它可以作为字符串名称或列索引给出。
df = pd.read_csv('telecom_data_2.csv', index_col='customer_id')
print(df.head())
Output:
gender age monthly_charges churn
customer_id
1 Male 34 56.2 No
2 Female 45 74.6 Yes
3 Female 23 66.7 No
4 Male 51 86.4 Yes
5 Female 30 54.6 No
这里,“customer_id”列用作 DataFrame 的索引。
跳行
“skiprows”参数允许您跳过某些行。这可以是指定行号的整数列表,也可以是根据行索引进行评估的可调用函数,如果应跳过该行则返回 true。
df = pd.read_csv('telecom_data_2.csv', skiprows=[1,2,3])
print(df.head())
Output:
customer_id gender age monthly_charges churn
0 4 Male 51 86.4 Yes
1 5 Female 30 54.6 No
2 6 Male 45 78.5 Yes
3 7 Female 25 56.6 No
4 8 Male 35 87.6 Yes
在本例中,将跳过第 1、2 和 3 行(按人数计算为第 2、3 和 4 行)。
有条件跳过
您还可以传递一个可调用函数来跳过索引与条件匹配的特定行:
df = pd.read_csv('telecom_data.csv', skiprows=lambda i: i % 2 == 0)
print(df)
Output:
CustomerID Gender SeniorCitizen Partner Dependents tenure PhoneService
0 5575 Male 0 No No 34 No
1 7795 Female 0 No No 45 No
正如您所看到的,DataFrame 现在仅包含奇数行,因为我们跳过了偶数行。
所有这一切都无需加载整个文件并消耗内存。
请注意,您只能针对行索引而不是行值使用可调用函数。
限制读取的行数
您可以使用“nrows”参数指定从数据开头读取多少行。
df = pd.read_csv('telecom_data_2.csv', nrows=10)
print(df)
Output:
customer_id gender age monthly_charges churn
0 1 Male 34 56.2 No
1 2 Female 45 74.6 Yes
2 3 Female 23 66.7 No
3 4 Male 51 86.4 Yes
4 5 Female 30 54.6 No
5 6 Male 45 78.5 Yes
6 7 Female 25 56.6 No
7 8 Male 35 87.6 Yes
8 9 Female 28 54.8 No
9 10 Male 50 82.4 Yes
在这里,我们仅读取文件的前 10 行。
获取特定列
usecols 参数有助于从 CSV 文件中获取列的子集。这可以是字符串序列(列名称)或整数序列(列索引)。
df = pd.read_csv('telecom_data_2.csv', usecols=['customer_id', 'age'])
print(df.head())
Output:
customer_id age
0 1 34
1 2 45
2 3 23
3 4 51
4 5 30
在这里,我们仅从 CSV 文件加载“customer_id”和“age”列。
提供列名称
如果 CSV 文件不包含标题,或者您想要替换现有标题,则可以使用“names”参数提供列名称列表。
df = pd.read_csv('telecom_data.csv', names=['ID', 'Gender', 'Age', 'Charges', 'Churn'])
print(df.head())
在这里,传递了新的列名称,即“ID”、“Gender”、“Age”、“Charges”、“Churn”,我们将使用它们作为列名称。
处理带引号的 CSV 文件
有时,CSV 文件的字段带有引号。默认情况下,pandas 将双引号视为标准。但是,如果文件使用另一个字符作为引号,则可以使用“quotechar”参数进行设置。
df = pd.read_csv('telecom_data.csv', quotechar="'")
此代码不会更改输出,但会在字段用单引号引起来时处理文件的加载。
控制数据类型
“dtype”参数允许您指定不同列的数据类型。这可以是一个字典,其中键可以是整数或列标签,值是 NumPy 数据类型。
df = pd.read_csv('telecom_data.csv', dtype={'customer_id': 'int64', 'age': 'float64'})
print(df.dtypes)
Output:
customer_id int64
gender object
age float64
monthly_charges float64
churn object
dtype: object
此处,“customer_id”列被强制具有整数 (int64) dtype,而“age”列被指定具有浮点 (float64) dtype。
注意:指定数据类型在性能方面起着重要作用。它可以加快加载大型数据集的速度。
处理布尔数据
如果您的数据包含以单词表示的布尔值(例如“是”/“否”或“Y/N”),则可以使用“true_values”和“false_values”参数将它们映射到布尔值。
df = pd.read_csv('telecom_data.csv', true_values=['Yes'], false_values=['No'])
print(df.head())
Output:
CustomerID Gender SeniorCitizen Partner Dependents tenure PhoneService
0 7590 Male 0 False False 1 True
1 5575 Male 0 False False 34 False
2 3668 Female 0 False False 2 True
3 7795 Female 0 False False 45 False
4 9237 Female 0 False False 2 True
此代码将整个 DataFrame 中的“是”和“否”解释为布尔值(True 和 False)。
解析日期列
您可以使用“parse_dates”参数来指定应解析为日期的列。
df = pd.read_csv('telecom_data.csv', parse_dates=['start_date'])
print(df.dtypes)
Output:
customer_id int64
gender object
age int64
monthly_charges float64
churn object
start_date datetime64[ns]
dtype: object
在这里,“start_date”列被解析为日期时间对象。
处理非美国日期格式
“dayfirst”参数用于告诉 pandas 将日期解释为 DD/MM (True) 或 MM/DD (False)。默认情况下,它设置为 False。
df = pd.read_csv('telecom_data.csv', parse_dates=['Activation_date'], dayfirst=True)
Output:
CustomerID Gender SeniorCitizen Partner Dependents tenure PhoneService ActivationDate
0 7590 Male 0 No No 1 Yes 2019-07-12
1 5575 Male 0 No No 34 No 2019-03-11
2 3668 Female 0 No No 2 Yes 2019-11-20
3 7795 Female 0 No No 45 No 2019-04-17
4 9237 Female 0 No No 2 Yes 2019-07-19
此代码不会更改输出,但会将“Activation_date”解释为 DD/MM。
删除不需要的空格
‘skipinitialspace’参数设置为 True 时,将跳过分隔符后面的空格。
df = pd.read_csv('telecom_data.csv', skipinitialspace=True)
读取压缩的 CSV 文件
“compression”参数允许您直接读取压缩的 CSV 文件。它可以设置为“gzip”、“zip”、“bz2”、“xz”或“infer”。如果设置为“infer”,pandas 将根据文件扩展名猜测压缩。
df = pd.read_csv('telecom_data.csv.zip', compression='zip')
print(df.head())
这将读取压缩的 CSV 文件并返回前五行。它的行为与读取未压缩的文件完全相同,因此输出将与来自pd.read_csv('telecom_data.csv')
line.
读取不同编码的CSV文件
如果您的 CSV 文件采用不同的编码,您可以使用“encoding”参数指定编码。
df = pd.read_csv('telecom_data.csv', encoding='Windows-1256')
这将读取带有“Windows-1256”编码的 CSV 文件。
读取大型 CSV 文件
如果您的 CSV 文件太大而无法装入内存,您可以分块读取该文件。
chunks = pd.read_csv('telecom_data.csv', chunksize=10000)
for chunk in chunks:
print(chunk.head())
此代码一次读取 10000 行的数据块,并打印每个块的前 5 行。
处理空行
“skip_blank_lines”参数指定是否应忽略空白行。 read_csv 函数默认将此参数设置为 True。如果为 False,则将它们视为 NaN。
考虑以下示例数据:
CustomerID,Gender,SeniorCitizen,Partner,Dependents,tenure,PhoneService
7590,Male,0,No,No,1,Yes
5575,Male,0,No,No,34,No
3668,Female,0,No,No,2,Yes
7795,Female,0,No,No,45,No
9237,Female,0,No,No,2,Yes
让我们看看读取这些数据会得到什么:
df = pd.read_csv('telecom_data.csv')
Output:
CustomerID Gender SeniorCitizen Partner Dependents tenure PhoneService
0 7590 Male 0 No No 1 Yes
1 5575 Male 0 No No 34 No
2 3668 Female 0 No No 2 Yes
3 7795 Female 0 No No 45 No
4 9237 Female 0 No No 2 Yes
如果将其设置为 True,您将得到以下结果:
df = pd.read_csv('telecom_data.csv', skip_blank_lines=False)
Output:
CustomerID Gender SeniorCitizen Partner Dependents tenure PhoneService
0 NaN NaN NaN NaN NaN NaN NaN
1 7590.0 Male 0.0 No No 1.0 Yes
2 NaN NaN NaN NaN NaN NaN NaN
3 5575.0 Male 0.0 No No 34.0 No
4 NaN NaN NaN NaN NaN NaN NaN
5 3668.0 Female 0.0 No No 2.0 Yes
6 NaN NaN NaN NaN NaN NaN NaN
7 7795.0 Female 0.0 No No 45.0 No
8 NaN NaN NaN NaN NaN NaN NaN
9 9237.0 Female 0.0 No No 2.0 Yes
处理 NaN 值
您可以使用“na_values”指定其他字符串以识别为 NaN。
默认情况下,以下值被解释为 NaN:'#N/A'、'NULL'、'null'、'N/A'、'#NA'、'-1.#IND'、'-1.# QNAN'、'-NaN'、'-nan'、'1.#IND'、'1.#QNAN'、''、'NA'、'NaN'、'n/a'、'nan'。
df = pd.read_csv('telecom_data.csv', na_values=['No Data', 'Missing'], keep_default_na=False, na_filter=True)
除了默认 NaN 值之外,此代码还将“无数据”和“缺失”视为 NaN。
与 read_csv 的回忆
我记得在埃及一家大型电信公司担任 Python 开发人员期间,有一个特别具有挑战性的项目。
我们正在进行一个涉及海量客户数据分析的综合项目。我们必须处理以 CSV 格式存储的大量数据集,每个文件都超过千兆字节。
我们不仅处理大文件,而且处理非常大的文件 - 想想 TB 级的文件。
最初,我们尝试使用传统的方式加载这些巨大的 CSV 文件pd.read_csv()
方法,但我们很快就遇到了障碍。
我们的机器即使具有高端规格,也无法将如此大的数据集加载到内存中。这个瓶颈威胁到我们的项目进展,显然我们需要一个更智能的解决方案。
就在那时,我深入研究了 Pandas 库,发现了chunksize
中的参数pd.read_csv()
功能。
The chunksize
参数允许 pandas 逐块读取文件,而不是尝试一次加载整个文件。
With chunksize
,我们能够以可管理的块的形式读取数据 - 我们发现每个块大约 10,000 行的最佳位置 - 有效地绕过了内存问题。
我们的 Python 脚本曾经因数据量巨大而崩溃,但现在运行平稳,可以顺利处理这些千兆字节大小的文件。
然而不久之后,另一个障碍又出现了。我们的客户数据的日期字段采用“DD-MM-YYYY”格式,这在埃及很常见,但它与美国通常使用的“MM-DD-YYYY”格式相反。
当 pandas 读取我们的 CSV 文件时,它错误地解析了日期,交换了日期和月份。因此,我们最终得到的数据表明客户在今年 13 月订阅了服务!
幸运的是,read_csv
function 再次拯救了我们。它包括一个dayfirst
参数,当设置为True
,指示 pandas 以“DD-MM-YYYY”格式解释日期。使用这个参数,我们能够准确地解析日期。
这是一个简单的解决方案,但它对我们的项目产生了巨大的影响。
我们从错误解析近 13% 的日期数据到实现近乎完美的准确性。
另一个障碍是当我处理电信数据库中包含客户反馈的另一个 CSV 文件时。
当我尝试使用标准读取此文件时pd.read_csv()
函数,我遇到了以下错误:
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xc3 in position 12: invalid continuation byte
出现这个错误是因为pandas使用的默认编码read_csv
函数是“utf-8”,但某些 CSV 文件不是。
这是一个简化的示例数据来说明问题:
id,feedback
1,"السرعة بطيئة جدا"
2,"التغطية ضعيفة في منطقتي"
如果您想要翻译,只是一些负面反馈
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)