二、我怎么读写表格文件
1、我想分析泰坦尼克号乘客数据,它们储存在csv文件中。
import pandas as pd
titanic = pd.read_csv("./data/titanic.csv")
pandas提供的read_csv()函数可将csv文件中的数据读取到DataFrame中。pandas支持许多文件格式:csv,excel,sql,jason,...。要读取它们,可以使用前缀read_+文件格式的函数形式。
读取数据之后最好应该检查一下。输入变量名,就可以展示出读取的DataFrame,默认是展示前5行和后5行:
titanic
PassengerId | Survived | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Cabin | Embarked | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 0 | 3 | Braund, Mr. Owen Harris | male | 22.0 | 1 | 0 | A/5 21171 | 7.2500 | NaN | S |
1 | 2 | 1 | 1 | Cumings, Mrs. John Bradley (Florence Briggs Th... | female | 38.0 | 1 | 0 | PC 17599 | 71.2833 | C85 | C |
2 | 3 | 1 | 3 | Heikkinen, Miss. Laina | female | 26.0 | 0 | 0 | STON/O2. 3101282 | 7.9250 | NaN | S |
3 | 4 | 1 | 1 | Futrelle, Mrs. Jacques Heath (Lily May Peel) | female | 35.0 | 1 | 0 | 113803 | 53.1000 | C123 | S |
4 | 5 | 0 | 3 | Allen, Mr. William Henry | male | 35.0 | 0 | 0 | 373450 | 8.0500 | NaN | S |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
886 | 887 | 0 | 2 | Montvila, Rev. Juozas | male | 27.0 | 0 | 0 | 211536 | 13.0000 | NaN | S |
887 | 888 | 1 | 1 | Graham, Miss. Margaret Edith | female | 19.0 | 0 | 0 | 112053 | 30.0000 | B42 | S |
888 | 889 | 0 | 3 | Johnston, Miss. Catherine Helen "Carrie" | female | NaN | 1 | 2 | W./C. 6607 | 23.4500 | NaN | S |
889 | 890 | 1 | 1 | Behr, Mr. Karl Howell | male | 26.0 | 0 | 0 | 111369 | 30.0000 | C148 | C |
890 | 891 | 0 | 3 | Dooley, Mr. Patrick | male | 32.0 | 0 | 0 | 370376 | 7.7500 | NaN | Q |
891 rows × 12 columns
2、我想查看DataFrame的前8行。
titanic.head(8)
PassengerId | Survived | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Cabin | Embarked | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 0 | 3 | Braund, Mr. Owen Harris | male | 22.0 | 1 | 0 | A/5 21171 | 7.2500 | NaN | S |
1 | 2 | 1 | 1 | Cumings, Mrs. John Bradley (Florence Briggs Th... | female | 38.0 | 1 | 0 | PC 17599 | 71.2833 | C85 | C |
2 | 3 | 1 | 3 | Heikkinen, Miss. Laina | female | 26.0 | 0 | 0 | STON/O2. 3101282 | 7.9250 | NaN | S |
3 | 4 | 1 | 1 | Futrelle, Mrs. Jacques Heath (Lily May Peel) | female | 35.0 | 1 | 0 | 113803 | 53.1000 | C123 | S |
4 | 5 | 0 | 3 | Allen, Mr. William Henry | male | 35.0 | 0 | 0 | 373450 | 8.0500 | NaN | S |
5 | 6 | 0 | 3 | Moran, Mr. James | male | NaN | 0 | 0 | 330877 | 8.4583 | NaN | Q |
6 | 7 | 0 | 1 | McCarthy, Mr. Timothy J | male | 54.0 | 0 | 0 | 17463 | 51.8625 | E46 | S |
7 | 8 | 0 | 3 | Palsson, Master. Gosta Leonard | male | 2.0 | 3 | 1 | 349909 | 21.0750 | NaN | S |
要查看DataFrame的前N行数据,请使用head()方法,并把行数N作为参数。而查看后N行,可以使用tail()方法,比如titanic.tail(10)将返回上面的DataFrame的后10行。
注:dtypes属性记录了每一列的数据类型,你可看一看pandas默认是怎么储存表格每一列数据的:
titanic.dtypes
PassengerId int64
Survived int64
Pclass int64
Name object
Sex object
Age float64
SibSp int64
Parch int64
Ticket object
Fare float64
Cabin object
Embarked object
dtype: object
可以看到,该DataFrame中数据类型包括整数(64位整型值int64表示)、浮点数(64位浮点数float64表示)、字符串(object表示)。
3、我想把泰坦尼克号乘客的数据保存到excel表格中。
titanic.to_excel('./data/titanic.xlsx', sheet_name='passengers', index=False)
正如 read_* 函数将文件中的数据导入内存中,to_* 方法可以将内存中存储的数据写入到文件里。比如:上述调用的to_excel()方法就能将titanic数据写入到excel表格中,sheet_name参数用于修改写入excel文件的sheet名,index=False则表名,每行开始的行标签不会被写入到文件中。
4、我想了解 DataFrame 的技术信息
titanic.info()
RangeIndex: 891 entries, 0 to 890
Data columns (total 12 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 PassengerId 891 non-null int64
1 Survived 891 non-null int64
2 Pclass 891 non-null int64
3 Name 891 non-null object
4 Sex 891 non-null object
5 Age 714 non-null float64
6 SibSp 891 non-null int64
7 Parch 891 non-null int64
8 Ticket 891 non-null object
9 Fare 891 non-null float64
10 Cabin 204 non-null object
11 Embarked 889 non-null object
dtypes: float64(2), int64(5), object(5)
memory usage: 83.7+ KB
info()方法展示了DataFrame的技术信息,让我们仔细看一下结果细节:
- 第一行的类名信息表明它确实是一个DataFrame对象
- 共有891个条目,行标签值从0到890。
- 共有12个列(不包括行标签),#列显示各列的列号,Column列显示了各列的列标签,Non-Null Count列表示非空值的个数,可以看到大多数列第一行都有数据(891 non-null),Age和Cabin列则不足891个非空值。
- Name,Sex,Cabin和Embarked列为文本数据,其他列都是数字型数据,包括整数和浮点数,它们都汇总在Dtype列。
- dtypes:统计了每种数据类型的个数
- 最后一行给出了DataFrame所占用的内存大小。
--------------分割线----------------
pandas的数据类型(dtype)
pandas从numpy衍生而来,因而大多数数据类型(dtype)都与numpy相同,比如float(浮点型),int(整型),bool(布尔型),timedelta64[ns](64位的以纳秒为单位的时间差类型)以及 datetime64[ns](不带时区的64位的以纳秒为单位的日期时间类型)。除此之外,pandas还扩展了一些新的数据类型,以下是一些常用的扩展类型:
数据类型 | 内在标量形式 | 字符串别名(用于参数传递) | 相关文档 |
---|---|---|---|
带时区的日期时间 | Timestamp | 'datetime64[ns,]' | 时区控制 |
分类变量 | (none) | 'category' | 分类数据(Categorical data) |
周期(时间段) | Period | 'period[]', 'Period[]' | 时间段表示 |
稀少数据 | (none) | 'Sparse', 'Sparse[int]', 'Sparse[float]' | 稀少数据结构 |
字符串 | str | 'string' | 处理文本数据 |
注:object是一种特殊的数据类型,它可以储存任何类型的python对象,当然也包括字符串。由于历史和兼容性等原因,它一直作为文本数据的默认数据类型,但这并不值得推荐,pandas为此提供了String类型,因此在自定义类型时应尽量使用后者,在性能等方面更具优势。
通常情况下,pandas会根据需要自动创建一种合适的数据类型(向上类型转换upcasting)以兼容所有数据,但你也可以根据自己的需要手动调整。
那么如何改变数据的类型呢?
- 你可以使用astype()方法,该方法会返回原DataFrame的副本(传递copy=False可以改变此行为),如果转变类型不合法,则会引发异常。
import numpy as np
import pandas as pd
df = pd.DataFrame({'A': pd.Series(np.random.randn(8), dtype='float16'),
'B': pd.Series(np.random.randn(8)),
'C': pd.Series(np.array(np.random.randn(8),
dtype='uint8'))})
df.dtypes
A float16
B float64
C uint8
dtype: object
df.astype('float32').dtypes
A float32
B float32
C float32
dtype: object
- 下面这三个函数都是针对一维数组的,它们可以将数组里面的对象转换成特定类型:
- pd.to_numeric()将数组的类型转换为数字型,根据数据的不同,返回float64和int64类型的数据。
m = ['1.1', 2, 3] # 包含了字符串
pd.to_numeric(m)
array([1.1, 2. , 3. ])
- pd.to_datetime()将字符串、python内置datetime对象、时间戳整数值等转换为pandas的datetime类型。
import datetime
m = ['2016-07-09', datetime.datetime(2016, 3, 2)]
pd.to_datetime(m)
DatetimeIndex(['2016-07-09', '2016-03-02'], dtype='datetime64[ns]', freq=None)
pd.to_datetime(1490195805, unit='s')
Timestamp('2017-03-22 15:16:45')
- pd.to_timedelta()将字符串数据等转化为timedelta数据。
m = ['5us', pd.Timedelta('1day')]
pd.to_timedelta(m)
TimedeltaIndex(['0 days 00:00:00.000005', '1 days 00:00:00'], dtype='timedelta64[ns]', freq=None)
- infer_objects()方法。我们知道object是一个通用的数据类型,什么都有。而在你剔除了某些“异类”之后不想再使用object类型时,你可以选择调用它,它会将object类型转换成一个推测(infer)的更好的类型。
df = pd.DataFrame({"A": ["a", 1, 2, 3]})
df.dtypes
A object
dtype: object
df = df.iloc[1:] # 删掉第一行的字符串
df.dtypes # 仍是object类型
A object
dtype: object
df.infer_objects().dtypes
A int64
dtype: object
----------分割线-----------
to_excel()用法延伸
上面可知to_excel()方法可以将DataFrame保存到Excel表格中,并用利用sheet_name参数修改相应的sheet名。那如果我想将两个不同的DataFrame保存到同一个Excel表格的不同sheet里,像下面这样对同一个文件连续调用两次to_excel()方法是否可以呢?
import numpy as np
df = pd.DataFrame({'A': pd.Series(np.random.randn(8), dtype='float16'),
'B': pd.Series(np.random.randn(8)),
'C': pd.Series(np.array(np.random.randn(8),
dtype='uint8'))})
titanic.to_excel('./data/multiplesheet.xlsx', sheet_name='titanic', index=False)
df.to_excel('./data/multiplesheet.xlsx', sheet_name='df', index=False)
打开保存的文件检查一下,
只有最后保存的一个sheet,看来向同一个文件连续调用两次方法是行不通的。这是因为,to_excel()命令在数据写入文件后就会将文件关闭以防止出现意外的写入错误。因此第二次再调用时相当于重新打开一遍该文件,所有操作都会将原文件覆盖掉。那要怎么解决这个问题呢?这时就需要python的上下文管理器with语句配合pandas支持的ExcelWriter(Excel编写器),ExcelWriter负责创建写入文件的对象,with语句则维持文件打开的状态直到全部写入操作完成。
with pd.ExcelWriter('./data/multiplesheet.xlsx') as writer:
# 创建一个写入文件的对象,并赋予writer别名,后续向writer写入数据即可
titanic.to_excel(writer, sheet_name="titanic", index=False)
df.to_excel(writer, sheet_name="df", index=False)
再检查一下文件
成功将两个DataFrame写入到同一个Excel表格中。
---------------------分割线------------------------------------------
titanic.csv下载地址:
https://github.com/pandas-dev/pandas/blob/master/doc/data/titanic.csv