pandas
numpy https://www.cnblogs.com/wwg945/articles/8661583.html
Series对象
Series 是一种一维数组,和 NumPy 里的数组很相似。事实上,Series 基本上就是基于 NumPy 的数组对象来的。和 NumPy 的数组不同,Series 能为数据自定义标签,也就是索引(index),然后通过索引来访问数组中的数据。
a = pd.Series(data=[100,200,300],index=["5月","6月","7月"]) print(a[0],a["5月"])
上面的 data 参数可以是任意数据对象,比如字典、列表甚至是 NumPy 数组,而index 参数则是对 data 的索引值,类似字典的 key。
用字典生成Series的时候, 也可以指定索引, 当索引中值不存在与字典的键的时候则次索引的值标记为NA.
a = pd.Series(data={"name":"li","sex":"男"},index=["name","age","sex"])
print(a)
通过函数pandas.isnull和pandas.notnull可以知道那个字段是空, 那个字段不是空
pd.isnull(a) ''' name False age True sex False dtype: bool ''' pd.notnull(a) ''' name True age False sex True dtype: bool '''
通过索引可以访问Series中的元素
a = pd.Series(data={"name":"li","sex":"男"},index=["name","age","sex"])
a[["name","age"]]
'''
name li
age NaN
dtype: object
'''
a["name"]
# li
获取所有的值
a.values # array(['li', nan, '男'], dtype=object)
获取所有的索引
a.index # Index(['name', 'age', 'sex'], dtype='object')
Series也可以使用bool索引
a = pd.Series(data={"2015":998,"2016":990,"2014":500})
a>990
'''
2015 True
2016 False
2014 False
dtype: bool
'''
运算
# 两个不同的Series是按照index来相加的
a = pd.Series(data={"2015":998,"2016":990,"2014":500})
b = pd.Series(data={"2013":998,"2014":990,"2015":500})
a+b
# 相同索引值元素相加, 不相同的会设置成NAN
'''
2013 NaN
2014 1490.0
2015 1498.0
2016 NaN
dtype: float64
'''
DataFrame
DataFrame对象是一种二维数组, 数据以表格的形式存储, 分成若干行和列。通过 DataFrame,你能很方便地处理数据。常见的操作比如选取、替换行或列的数据,还能重组数据表、修改索引、多重筛选等。
创建DataFrame对象
通过Series来创建DataFrame
info = {"name":pd.Series(["金角","银角","太白","小旋风"]),
"age":pd.Series(['998','1000','5000','200']),
"weapon":pd.Series(["幌金绳","紫金葫芦","七星剑","号令旗"])}
pd.DataFrame(info)
# 这个字典的键是每一列的名称, 相同位置的元素成为行
通过字典来创建DataFrame, 结果与上面相同, 行的索引为数字索引
info = {"name":["金角","银角","太白","小旋风"],
"age":['998','1000','5000','200'],
"weapon":["幌金绳","紫金葫芦","七星剑","号令旗"]}
a = pd.DataFrame(info)
像上面那种其实已经有列的名字了 ,另外还可以根据二维列表来创建DataFrame对象, 不过这样行和列的索引就都变成了数字了
df = pd.DataFrame(np.random.randn(6,4)) print(df)
DataFrame也可以设置行索引, 不过一般行数是不确定的, 这个一般也不设置
info = {"name":["金角","银角","太白","小旋风"],
"age":['998','1000','5000','200'],
"weapon":["幌金绳","紫金葫芦","七星剑","号令旗"]}
a = pd.DataFrame(info,index=["老大","老二","老三","老四"])
不仅仅是可以设置行索引, 还可以设置列索引
df = pd.DataFrame(np.random.randn(6,4), columns=list('ABCD'))
print(df)
列操作
获取列索引
df = pd.DataFrame(np.random.randn(6,4),index=pd.date_range("20130101",periods=6), columns=list('ABCD'))
column = df.columns
print(column)
查看每一列的类型
df = pd.DataFrame(np.random.randn(6,4), columns=list('ABCD'))
print(df.dtypes)
要获取一列的数据,还是用中括号 [] 的方式, 当取1列是返回的Series对象
info = {"name":["金角","银角","太白","小旋风"],
"age":['998','1000','5000','200'],
"weapon":["幌金绳","紫金葫芦","七星剑","号令旗"]}
a = pd.DataFrame(info)
a["name"]
type(a["name"])
获取多列时,返回的是DataFrame类型
info = {"name":["金角","银角","太白","小旋风"],
"age":['998','1000','5000','200'],
"weapon":["幌金绳","紫金葫芦","七星剑","号令旗"]}
a = pd.DataFrame(info)
a[["name","age"]]
type(a[["name","age"]])
添加一列, 可以定义一个Series(或者是字典),并放入一个列中
info = {"name":["金角","银角","太白","小旋风"],
"age":['998','1000','5000','200'],
"weapon":["幌金绳","紫金葫芦","七星剑","号令旗"]}
year = ["0000","0001","0002","0003"]
a = pd.DataFrame(info)
a["year"] = year
或者是通过已存在的两列生成一列
info = {"name":["金角","银角","太白","小旋风"],
"age":['998','1000','5000','200'],
"weapon":["幌金绳","紫金葫芦","七星剑","号令旗"]}
year = ["0000","0001","0002","0003"]
a = pd.DataFrame(info)
a["year"] = year
a["year_age"] = a["year"]+a["age"]
删除行或列
drop方法可以删除通过指定axis来删除行或列. 0对应的行, 1对应的是列
# 删除第0行
info = {"name":["金角","银角","太白","小旋风"],
"age":['998','1000','5000','200'],
"weapon":["幌金绳","紫金葫芦","七星剑","号令旗"]}
year = ["0000","0001","0002","0003"]
a = pd.DataFrame(info)
a.drop(0,axis=0)
# 删除name列
info = {"name":["金角","银角","太白","小旋风"],
"age":['998','1000','5000','200'],
"weapon":["幌金绳","紫金葫芦","七星剑","号令旗"]}
year = ["0000","0001","0002","0003"]
a = pd.DataFrame(info)
a.drop("name",axis=1)
要注意的是drop返回的内容是修改后的, 并不会对原数据进行修改, 除非加上inplace=True 参数
行操作
获取
df = pd.DataFrame(np.random.randn(6,4), index=pd.date_range("20130101",periods=6)
, columns=list('ABCD'))
# 获取前几行, 默认5, 可以指定行数
head= df.head(3)
# 获取后几行, 默认5, 可以指定行数
tail = df.tail(3)
# 通过切片获得行
df[0:3] # 可以通过行的数字序号
df['20130102':'20130104'] # 也可以通过行的索引
获取行索引
df = pd.DataFrame(np.random.randn(6,4),index=pd.date_range("20130101",periods=6), columns=list('ABCD'))
index = df.index
print(index)
添加一行
df = pd.DataFrame(np.random.randn(2,4),index=pd.date_range("20130101",periods=6), columns=list('ABCD'))
df.append(df.iloc[1])
关于选取
在Dataframe中选取数据大抵包括3中情况:
1)行(列)选取(单维度选取):df[]。这种情况一次只能选取行或者列,即一次选取中,只能为行或者列设置筛选条件(只能为一个维度设置筛选条件)。
2)区域选取(多维选取):df.loc[],df.iloc[],df.ix[]。这种方式可以同时为多个维度设置筛选条件。
3)单元格选取(点选取):df.at[],df.iat[]。准确定位一个单元格。
行列的选取:
选行
df = pd.DataFrame(np.random.randn(6,4),index=pd.date_range("20130101",periods=6), columns=list('ABCD'))
print(df[0:1]) # 选行的时候不能直接使用索引, 使用索引的话就成了选列了, 数字索引,顾头不顾尾
print(df['20130102':'20130104']) # 设置的行索引, 顾头又顾尾
print(df[[True,True,True,False,False,False]]) # 布尔索引, 返回True的行
index = df["C"] >0.5
# print(index)
print(df[index]) # 通过运算构建布尔索引
print(df[(df["C"] >0.5) & (df["C"] <0.7) ]) # 且,
print(df[(df["C"] <0.5) | (df["C"] >0.7) ]) # 或
选列
df = pd.DataFrame(np.random.randn(6,4),index=pd.date_range("20130101",periods=6), columns=list('ABCD'))
print(df["A"]) # 选单列
print(df[["A","B"]]) # 选多列
区域选取
区域选取可以从多个维度(行和列)对数据进行筛选,可以通过df.loc[],df.iloc[],df.ix[]三种方法实现。采用df.loc[],df.iloc[],df.ix[]这三种方法进行数据选取时,方括号内必须有两个参数,第一个参数是对行的筛选条件,第二个参数是对列的筛选条件,两个参数用逗号隔开。df.loc[],df.iloc[],df.ix[]的区别如下:
df.loc[]只能使用标签索引,不能使用整数索引,通过便签索引切边进行筛选时,前闭后闭。
df.iloc[]只能使用整数索引,不能使用标签索引,通过整数索引切边进行筛选时,前闭后开。;
df.ix[]既可以使用标签索引,也可以使用整数索引。
下面就只示范一种就可以了, 区域选取更类似于花式索引, 选行和选列通过,隔开
df = pd.DataFrame(np.random.randn(6,4),index=pd.date_range("20130101",periods=6), columns=list('ABCD'))
print(df.iloc[0,:]) # 第一行所有列
print(df.iloc[[0,1,3],:]) # 指定三行的所有列
print(df.iloc[0:3,:]) # 前三行的所有列
# 后面布尔和组合的就不写了
print(df.iloc[:,1]) # 第一列
# 不想写了, 其实都是差不多的, 补充一个取值的吧, 选行和列如果简单的运算不够用的话可以指定函数
# 实际上还是布尔索引
print(df[lambda df:df['A'] > 0.5]) # 选取A行大于0.5的
单元格选取
单元格选取包括df.at[]和df.iat[]两种方法。df.at[]和df.iat[]使用时必须输入两个参数,即行索引和列索引,其中df.at[]只能使用标签索引,df.iat[]只能使用整数索引。df.at[]和df.iat[]选取的都是单个单元格(单行单列),所以返回值都为基本数据类型。
df = pd.DataFrame(np.random.randn(6,4),index=pd.date_range("20130101",periods=6), columns=list('ABCD'))
print(df.iat[0,0])
关于布尔索引与缺失值填充
dataframe中不仅仅可以对某一列(行无法单独取)进行运算来获得布尔索引, 还可以对整个DataFrame进行运算来获得布尔索引(不要问我怎么对行运算获得布尔索引, 我不会告诉你行列转换的)
df = pd.DataFrame(np.random.randn(6,4),index=pd.date_range("20130101",periods=6), columns=list('ABCD'))
print(df["A"]>0)
print(df[df["A"]>0])
print(df>0)
print(df[df>0]) # 这样得到的值中不满足条件的就会变成NAN, 下面就来介绍对于缺失值的处理
df1 = df[df>0]
# 方案一: 删除缺少数据的行
df1.dropna(how="any") # any是行或者列包含nan的, axis默认=0,删除行
# 方案二: 填写填充的数据
df1.fillna(value=5)
# 除设置指定值外, 还可以设置附近的值来填充
df1 = df1.fillna(method='bfill',axis=0,limit=1) # 那纵向后面的limit个元素的平均值填充
df1 = df1.fillna(method='ffill',axis=0,limit=1) # 那纵向前面的limit个元素的平均值填充
print(df1)
# 获取为nan的布尔索引
print(pd.isna(df1))
其他方法
apply(): 将DataFrame的一行或一列传入指定的函数中
import pandas as pd
import math
ls = [
[1,2,3,4,5],
[4,5,6,7,8],
[3,5,8,3,1],
]
df = pd.DataFrame(ls)
# axis=0 将函数应用于每一列
# axis=1 将函数应用于每一行
print(df.apply(lambda s:s.max()))
data_range: 创建时间日期的索引列
import numpy as np
import pandas as pd
dates = pd.date_range("20130101",periods=6)
# print(dates)
# 默认时间差为天, 通过freq可以设置, 常用的有D:日, W:周,
# 更多就参见http://pandas.pydata.org/pandas-docs/stable/user_guide/timeseries.html#timeseries-offset-aliases
dates = pd.date_range("20130101",periods=6,freq="W")
# print(dates)
# 可以用这一列做为DataFrame的索引列
df = pd.DataFrame(np.random.randn(6,4), index=dates, columns=list('ABCD'))
print(df)
显示数据值(无索引)
df = pd.DataFrame(np.random.randn(6,4),index=pd.date_range("20130101",periods=6), columns=list('ABCD'))
value = df.values
print(value)
显示数据的统计
df = pd.DataFrame(np.random.randn(6,4),index=pd.date_range("20130101",periods=6), columns=list('ABCD'))
desc = df.describe()
print(desc, type(desc)) # 返回的也是一个dataframe,
行列转换
df = pd.DataFrame(np.random.randn(6,4),index=pd.date_range("20130101",periods=6), columns=list('ABCD'))
fd = df.T
print(fd)
排序
df = pd.DataFrame(np.random.randn(6,4),index=pd.date_range("20130101",periods=6), columns=list('ABCD'))
# 按轴排序
df = df.sort_index(axis=1, ascending=False) # 将列排序,降序
print(df)
df = df.sort_index(axis=0, ascending=False) # 将行排序
print(df)
# 按值排序
df = pd.DataFrame(np.random.randn(6,4),index=pd.date_range("20130101",periods=6), columns=list('ABCD'))
df = df.sort_values(by="B") # 按照B列中的内容将行排序
print(df)
去重
drop_duplicate去除特定列下面的重复行。返回DataFrame格式的数据。
# 其中包含三个参数
subset : column label or sequence of labels, optional # 用来指定特定的列,默认所有列
keep : {‘first’, ‘last’, False}, default ‘first’ # 删除重复项并保留第一次出现的项
inplace : boolean, default False # 是直接在原来数据上修改还是保留一个副本
实践
import pandas as pd
import math
df = pd.DataFrame({"A":[1,1,2,2],'B':["a","b","c","c"]})
print(df.drop_duplicates("A","first"))
print(df.drop_duplicates(["A","B"],"last"))
合并与分组
合并
# 构造三个两行四列的DataFrame
df1 = pd.DataFrame(np.random.randn(2, 4))
df2 = pd.DataFrame(np.random.randn(2, 4))
df3 = pd.DataFrame(np.random.randn(2, 4))
# 使用concat
# print(pd.concat([df1,df2,df3])) # 此时是固定列, 纵向添加 通过设置axis改为固定行,横向添加
# print(pd.concat([df1,df2,df3], axis=1))
# 此外还可以指定join参数, 默认的是outer, 得到的是并集, 可以设置为inner, 得到的就是交集了
df1 = pd.DataFrame(np.random.randn(2, 4), columns=list("ABCD"))
df2 = pd.DataFrame(np.random.randn(2, 4), columns=list("CDEF"))
# 通过内联得到的只有同名的列, 外联会补充NAN
print(pd.concat([df1, df2], join="inner"))
# 使用merge, merge更像是数据库的连表
df1 = pd.DataFrame({"name": ["金角", "银角", "太白", "小旋风"],
"age": ['998', '1000', '5000', '200']})
df2 = pd.DataFrame({"name": ["金角", "银角", "太白", "黑旋风"],
"weapon": ["幌金绳", "紫金葫芦", "七星剑", "号令旗"]})
print(pd.merge(df1,df2, on="name")) # 用name将两个表连接
# 当关联的两行或者两列不是同名时, 可以通过设置left_on和right_on手动指定merge中左右两边的哪一列列作为连接的列
分组, 不过这里的输出你是看不见的
df = pd.DataFrame({'A': ['a', 'b', 'a', 'c', 'a', 'c', 'b', 'c'],
'B': [2, 8, 1, 4, 3, 2, 5, 9],
'C': [102, 98, 107, 104, 115, 87, 92, 123]})
# 按某一列分组
print(df.groupby("A"))
# 获取zhe这一列某一个值对应的行
print(df.groupby("A").get_group("a"))
# 按多列进行分组
print(df.groupby(["A","B"]))
# 分组后是可以选列的
print(df.groupby("A")["B"])
print(df.groupby("A")[["A","B"]]) # 选多列
聚合方法
sum(),mean(),max(),min(),size(),describe()
df = pd.DataFrame({'A': ['a', 'b', 'a', 'c', 'a', 'c', 'b', 'c'],
'B': [2, 8, 1, 4, 3, 2, 5, 9],
'C': [102, 98, 107, 104, 115, 87, 92, 123]})
print(df.groupby("A")[["A","B"]].mean()) # 平均值
print(df.groupby("A")[["A","B"]].sum()) # 求和
print(df.groupby("A")[["A","B"]].max()) # 最大值
print(df.groupby("A")[["A","B"]].mean()) # 平均值
# size跟count的区别: size计数时包含NaN值,而count不包含NaN值
print(df.groupby("A")[["A","B"]].size()) # 数量
print(df.groupby("A")[["A","B"]].count()) # 数量
# 分组运算方法, 为不同的列使用不同的聚合函数
print(df.groupby("A")[["A","B"]].agg({"A":"sum","B":"max"}))
# 也可以求一列的多个聚合函数
print(df.groupby("A")["B"].agg({"sum":"sum","max":"max"}))
数据的读取和写入
CSV
df = pd.DataFrame(np.random.randn(2,4),index=pd.date_range("20130101",periods=6), columns=list('ABCD'))
# 读取
pd.read_csv("file")
# 写入
df.to_csv("file")
Excel
df = pd.DataFrame(np.random.randn(2,4),index=pd.date_range("20130101",periods=6), columns=list('ABCD'))
# 读取
pd.read_excel("file",sheetname)
# 写入
df.to_excel("file",sheetname)
最后来几道题吧
一: 有一个N行M列的二维数组, 写一个函数, 把值大于3的行取出来, 组成一个X行M列的新数组
import pandas as pd
ls = [
[1,2,3,4,5],
[4,5,6,7,8],
[3,5,8,3,1],
]
def filter(array):
df = pd.DataFrame(array)
# 首先df.T, 行转列, 然后找最小值大于3的列, 得到布尔索引, 然后用布尔索引直接取
return df[df.T.min()>3].values.tolist()
ret = filter(ls)
print(ret)

浙公网安备 33010602011771号