在本部分中,学习将数据导入Python的多种方法:
(i)来自平面文件,如.txts和.csvs;
(ii)从原生到其他软件的文件,如Excel电子表格,Stata,SAS和MATLAB文件;
(iii)来自关系数据库,例如SQLite和PostgreSQL。
平面文件(flat file)是去除了所有特定应用(程序)格式的电子记录,从而使数据元素可以迁移到其他的应用上进行处理。这种去除电子数据格式的模式可以避免因为硬件和专有软件的过时而导致数据丢失。 平面文件是一种计算机文件,所有信息都在一个信号字符串中。
1、导入整个文本文件
# Open a file: file
file = open('moby_dick.txt', 'r')
# Print it
print(file.read())
# Check whether file is closed
print(file.closed)
# Close file
file.close()
# Check whether file is closed
print(file.closed)
2、逐行导入文本文件
# Read & print the first 3 lines
with open('moby_dick.txt') as file:
#print(file.read())
print(file.readline())
print(file.readline())
print(file.readline())
CHAPTER 1. Loomings.
Call me Ishmael. Some years ago--never mind how long precisely--having
3、使用NumPy导入平面文件
np.loadtxt(file, delimiter=',')
# Import package
import numpy as np
# Assign filename to variable: file
file = 'digits.csv'
# Load file as array: digits
digits = np.loadtxt(file, delimiter=',')
# Print datatype of digits
print(type(digits)) # <class 'numpy.ndarray'>
# Select and reshape a row
im = digits[21, 1:]
im_sq = np.reshape(im, (28, 28))
# Plot reshaped data (matplotlib.pyplot already loaded as plt)
plt.imshow(im_sq, cmap='Greys', interpolation='nearest')
plt.show()
自定义NumPy导入
np.loadtxt(file, delimiter='\t', skiprows=1, usecols=[0,2])
delimiter:changes the delimiter that loadtxt()
is expecting, for example, you can use ','
and '\t'
for comma-delimited and tab-delimited respectively。
skiprows:需要忽略的行数(从文件开始处算起),或需要跳过的行号列表(从0开始)
usecols:获取希望保留的列的索引列表
我们要导入的.txt文件它有标题,且由字符串组成,是制表符分隔的。
由于标题,如果尝试使用np.loadtxt()按原样导入它,Python会抛出一个ValueError并告诉它无法将字符串转换为float。
有两种方法可以解决这个问题:首先,将数据类型参数dtype设置为str(对于字符串)。
或者,使用skiprows参数跳过第一行。使用skiprows=1,去掉标题行
# Import numpy
import numpy as np
# Assign the filename: file
file = 'digits_header.txt'
# Load the data: data
data = np.loadtxt(file, delimiter='\t', skiprows=1, usecols=[0,2])
# Print data
print(data)
[[ 1. 0.]
[ 0. 0.]
[ 1. 0.]
[ 2. 1.]]
np.loadtxt()输出为多维数组,可以按照数组切片等方式取数。
# Assign filename: file
file = 'seaslug.txt'
# Import file: data
data = np.loadtxt(file, delimiter='\t', dtype=str)
# Print the data
print(data)
# Import data as floats and skip the first row: data_float
data_float = np.loadtxt(file, delimiter='\t', dtype=float, skiprows=1)
# Print the data_float
print(data_float)
[["b'Time'" "b'Percent'"]
["b'99'" "b'0.067'"]
["b'99'" "b'0.133'"]
......
["b'5'" "b'0.214'"]
["b'5'" "b'0.4'"]]
[[ 9.90000000e+01 6.70000000e-02]
[ 9.90000000e+01 1.33000000e-01]
......
[ 5.00000000e+00 2.14000000e-01]
[ 5.00000000e+00 4.00000000e-01]]
使用混合数据类型
大多数情况下,需要导入在不同列中具有不同数据类型的数据集; 例如,一列可能包含字符串和另一列包含浮点数。 函数np.loadtxt()没法解决。 还有另一个函数,np.genfromtxt(),它可以处理这样的结构。 如果我们将dtype = None传递给它,它将确定每列应该是什么类型。np.recfromcsv()类似。
data = np.genfromtxt('titanic.csv', delimiter=',', names=True, dtype=None)
这里,第一个参数是文件名,第二个参数指定分隔符,第三个参数names告诉我们有一个标题。 由于数据类型不同,因此数据是一个称为结构化数组的对象。 因为numpy数组必须包含所有相同类型的元素,所以结构化数组通过作为一维数组来解决这个问题,其中数组的每个元素都是导入的平面文件的一行。
In [2]: np.shape(data)
Out[2]: (10,)
In [5]: print(data)
[(1, 0, 3, b'male', 22.0, 1, 0, b'A/5 21171', 7.25, b'', b'S')
(2, 1, 1, b'female', 38.0, 1, 0, b'PC 17599', 71.2833, b'C85', b'C')
(3, 1, 3, b'female', 26.0, 0, 0, b'STON/O2. 3101282', 7.925, b'', b'S')
(4, 1, 1, b'female', 35.0, 1, 0, b'113803', 53.1, b'C123', b'S')
(5, 0, 3, b'male', 35.0, 0, 0, b'373450', 8.05, b'', b'S')
(6, 0, 3, b'male', nan, 0, 0, b'330877', 8.4583, b'', b'Q')
(7, 0, 1, b'male', 54.0, 0, 0, b'17463', 51.8625, b'E46', b'S')
(8, 0, 3, b'male', 2.0, 3, 1, b'349909', 21.075, b'', b'S')
(9, 1, 3, b'female', 27.0, 0, 2, b'347742', 11.1333, b'', b'S')
(10, 1, 2, b'female', 14.0, 1, 0, b'237736', 30.0708, b'', b'C')]
# Assign the filename: file
file = 'titanic.csv'
# Import file using np.recfromcsv: d
d = np.recfromcsv(file,delimiter=',',names=True,dtype=None)
# Print out first three entries of d
print(d[:3])
[(1, 0, 3, b'male', 22.0, 1, 0, b'A/5 21171', 7.25, b'', b'S')
(2, 1, 1, b'female', 38.0, 1, 0, b'PC 17599', 71.2833, b'C85', b'C')
(3, 1, 3, b'female', 26.0, 0, 0, b'STON/O2. 3101282', 7.925, b'', b'S')]
4、使用pandas将平面文件导入为DataFrames
可以将包含具有不同数据类型的列的平面文件导入为numpy数组。 但是,pandas中的DataFrame对象是一个更适合存储此类数据的结构,幸运的是,我们可以使用pandas函数read_csv()和read_table()轻松地将混合数据类型的文件导入为DataFrame。
# Import pandas as pd
import pandas as pd
# Assign the filename: file
file = 'titanic.csv'
# Read the file into a DataFrame: df
df = pd.read_csv(file)
# View the head of the DataFrame
print(df.head())
PassengerId Survived Pclass Sex Age SibSp Parch Ticket Fare Cabin Embarked
0 1 0 3 male 22.0 1 0 A/5 21171 7.2500 NaN S
1 2 1 1 female 38.0 1 0 PC 17599 71.2833 C85 C
2 3 1 3 female 26.0 0 0 STON/O2. 3101282 7.9250 NaN S
3 4 1 1 female 35.0 1 0 113803 53.1000 C123 S
4 5 0 3 male 35.0 0 0 373450 8.0500 NaN S
自定义pandas导入
data = pd.read_csv(file, sep='\t', comment='#', na_values='Nothing')
comment:表示在文件中出现注释的字符,在本例中为“#”。
na_values:将字符串列表识别为NA / NaN,在本例中为字符串'Nothing'