pandas的一些学习和使用
1. 文件操作
1.1. 文件读取
import pandas as pd
data= pd.read_csv(data_path, sep=",")
# 当读取路径中包含中文的文件,且中文文件编码为utf8的时候,需要使用open操作,否则会报错。【之前会报错,最近不适用open读取路径中包含中文的时候,也不会报错了,不知道是否是pandas解决了这个问题】
data= pd.read_csv(open(data_path, encoding="utf8"), sep=",")
1.2. 文件写入
# index=None写入的时候不写入pandas自己生成的索引列,
# header=None 写入的时候不写入列名(第一行)
df_d.to_csv(data_path, index=None, header=None)
2. 切片操作
2.1. 常用操作整理和说明,参考here
loc: 基于行、列的label
iloc: 基于行和列的index
at:根据指定行、列的label定位
iat:根据行、列的index定位
ix:loc和iloc的结合体,既可以通过index,也可以通过label来定位
2.2. loc iloc
import pandas as pd
import numpy as np
df = pd.DataFrame({'name': ['Mary', 'Tom', 'Jack','Jim','Tonny'],
'age': [20,22,17,30,40],
'sex': ['Female', 'Male', 'Male', 'Male', 'Female']})
# 为了清晰说明loc iloc的区别,这里定义了行索引
df.index = ['A','B','C','D','E']
# 这两个是等价的,loc选择的是从第A行到第C行,列为name和age的内容。
# 等价于iloc中从第1行到第3行,列为第0,1列。
df.loc['A':'C', ['name','age']]
df.iloc[1:4, [0,1]]
# 上面对行进行了切片,列也可以进行切片。
df.loc['A':'B', 'name':'sex']
df.iloc[1:3, 0:3]
2.3. at iat
# 同理,这两个的结果是一样的
df.at['A','name']
df.iat[0,0]
# 当然使用loc也可以实现相同的操作。
df.loc['A','name']
2.4. ix
# 混合使用,索引和label混合使用也是可以的
df.ix[0,'name']
df.ix['A',0]
3. 其他基础操作
3.1. 删除指定索引列
# 使用列名、行名进行删除, inplace表示直接在df对象上修改,也就是不返回结果
df.drop(columns=['name','age'], inplace=True)
df.drop(index=['A', 'C'],inplace=True)
# 使用索引删除
df.drop(df.columns[[1,2]], axis=1, inplace=True)
df.drop(df.index[[1,2]], axis=0,inplace=True)
# 使用切片
# 删除第1-3列(不包含第3列)
df.drop(df.columns[1:3], axis=1, inplace=True)
3.2. 指定索引位置增加新列
DataFrame.insert(loc, column, value, allow_duplicates=False)
- loc int, insertion index, 取值范围为0到len(columns)
- column string, number等 列名
- value int Series array-like
# 直接在df上进行的修改,返回值为None
df.insert(2, 'height', 180) # 180是int类型,此时该列的所有值都是180。
3.3. 遍历并修改
for index, row in df.iterrows():
print(index, row['name']) # index是行索引,A,B,C,D,E;row表示该行的所有列值,使用对应的列名就可以得到对应的值
# 修改值
# 下面代码:如果年龄大于20,就将年龄修改为error
for index, row in df.iterrows():
if row['age'] > 20:
df.loc[index, 'age'] = 'error'
3.4. 提取dataframe中某些列成为一个新的dataframe
df_new = df[['name','age']]
3.5. 将某一列设置为索引列
df = df.set_index('name') # 这个需要接收返回值。
3.6. 删除重复数据和写入文件
drop_duplicate(subset=None, keep=‘first’, inplace=False)
- subset: column label or sequence of labels, optional
- keep first, last, False, 删除并保留第一次出现(最后一次出现)的项
- inplace False, True True表示直接在原来的数据上进行修改
# 删除重复数据,根据name列去重,也就是删除列name中值一样的记录,保存最后一个。
df.drop_duplicates('name','last', inplace=True)
3.7. 列名重命名
df.rename(columns={'name':'姓名','age':'年龄','sex':'性别'})
4. 统计
4.1. 统计某一列中不同的值和该值出现的次数
res = df['sex'].value_counts()
res
# Male 3
# Female 2
# Name: sex, dtype: int64
type(res) # pandas.core.series.Series
# 访问对应的值和次数
res.index # Index(['Male', 'Female'], dtype='object')
res.values # array([3, 2], dtype=int64)
res.to_numpy # 同上
res.to_list # [3, 2]
4.2. 根据指定列值进行筛选
# 将返回df中符合列名为column_name,值为Mary的df
df = df[df['colume_name'] == 'Mary']
5. Series(序列)
Series是带有标签的一维数组,可以保存任何数据类型(整数,字符串,浮点数,Python对象等)。轴标签统称为索引。创建Series的基本方法是调用:
s = pd.Series(data, index=index)
这里,data可以是许多不同的东西:
- Python dict(字典)
- ndarray
- 标量值(如5)
- list
传入的索引是轴标签的列表。
5.1. 创建Series
# 此时的data是ndarray,索引的长度需要和数据长度相同,如果没有传入索引,会自动创建[0至len(data)-1]长度的索引
s = pd.Series(np.random.randn(5), index=['a','b','c','d','e'])
s = pd.Series([1,3,6,np.nan,44,1])
s.index
Out[4]:
a 0.2735
b 0.6052
c -0.1692
d 1.8298
e 0.5432
dtype: float64
Out[5]: Index([u'a', u'b', u'c', u'd', u'e'], dtype='object')
使用标量的时候。
s = pd.Series(5, index=['a','b','c','d','e'])
s
Out[10]:
a 5.0
b 5.0
c 5.0
d 5.0
e 5.0
dtype: float64
具体使用字典的时候这里就暂时不显示,目前很少用到。
5.2. 获取元素索引对应的值
# Series 可以看做一个固定大小的字典,可以通过使用index作为索引来获取和设置值
s['a']
s['b'] = 12
# 判断是否有e这个索引值
'e' in s
# 获取某个索引的值,有两种方法
s['f'] # 若不存在f索引,则会报错
s.get('f') # 若不存在f索引,则会返回None,或者指定默认值
5.2.1. 运算
和Numpy数组方法一致,不用一个值一个值遍历序列
s = pd.Series(np.array([1,2,3,4,5]))
s+s
s*3 # 每一个值对应乘三,结果[3,6,9,12,15]
np.exp(s) #对每一个值求其以e为底的值
与numpy数组不同的地方在于:Series上的操作会自动根据标签自动对齐数据,比如:可以分别看一下s[1:] 和 s[:-1]
s[1:]+s[:-1]
0 NaN
1 4.0
2 6.0
3 8.0
4 NaN
dtype: float64
6. DataFrame
DataFrame是带有标签的二维数据结构,列的类型可能不同,可以想象成一个电子表格或者SQL表。
DataFrame是带有标签的二维数据结构,列的类型可能不同。你可以把它想象成一个电子表格或SQL表,或者 Series 对象的字典。它一般是最常用的pandas对象。像 Series 一样,DataFrame 接受许多不同类型的输入:
- 一维数组,列表,字典或 Series 的字典
- 二维 numpy.ndarray
- 结构化或记录 ndarray
- Series
- 另一个DataFrame
和数据一起,您可以选择传递index(行标签)和columns(列标签)参数。如果传递索引或列,则会用于生成的DataFrame的索引或列。因此,Series 的字典加上特定索引将丢弃所有不匹配传入索引的数据。
6.1. DataFrame的属性
主要包含 index, columns, dtypes, values, shape
df.index # Index(['A', 'B', 'C', 'D', 'E'], dtype='object')
df.columns #Index(['name', 'age', 'sex'], dtype='object')
df.dtypes
# name object
# age int64
# sex object
# dtype: object
df.values # 将dataframe转化为numpy的数组类型,可以使用这个属性进行转化
# array([['Mary', 20, 'Female'],
# ['Tom', 22, 'Male'],
# ['Jack', 17, 'Male'],
# ['Jim', 30, 'Male'],
# ['Tonny', 40, 'Female']], dtype=object)
df.shape # (5,3)
6.2. 使用Series和字典构造DataFrame
index是各种列索引的并集,
d = {
'one': pd.Series([1,2,3], index=['a','b','c']),
'two': pd.Series([1,2,3,4], index=['a','b','c','d'])
}
df = pd.DataFrame(d)
# df = pd.DataFrame({'time':pd.Series(time), 'count':pd.Series(count)})
df = pd.DataFrame(d, index=['c','a','d'])
df = pd.DataFrame(d, index=['c','a','d'], columns=['two','three'])
df
one two
a 1.0 1
b 2.0 2
c 3.0 3
d NaN 4
# 如果在DataFrame中增加了index和columns两个属性,那么在新建对象的时候新增的索引和列会根据Series中的index取
one two
c 3.0 3
a 1.0 1
d NaN 4
two three
c 3 NaN
a 1 NaN
d 4 NaN
6.3. 创建只有列索引的空DataFrame
list_columns = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11']
df_local = pd.DataFrame(columns=list_columns) # 创建一个只有列索引的空数据
df_local
6.4. 时间日期的操作
6.4.1. 转换成时间类型
# 将数据类型object转换成日期类型
df['time'] = pd.to_datetime(df['time'])
6.5. 常用方法
6.5.1. min()
score = np.array([[80, 88], [82, 81], [84, 75], [86, 83], [75, 81]])
df = pd.DataFrame(score, columns=['math','english'])
df.min() # 获取每一列的最小值
type(df.min()) # pandas.core.series.Series
6.5.2. 标准化
# 标准化, gray.min()获取的是每一列的最小值 gray——DataFrame结构
# 计算灰色关联分析里面得到的
gray=(gray - gray.min()) / (gray.max() - gray.min())