导图社区 一张图看懂pandas.DataFrame库精校版
python中pandas.DataFrame库详细精编,量化交易必备,希望这份脑图会对你有所帮助。
编辑于2023-05-17 17:01:29 北京市中心主题
浮动主题
pandas.DataFrame
一、DataFrame创建
DataFrame是以命名 列方式组织的行数据集录,默认行标为以0开始的序列,列标为各个列命名。
1.基于列表(或numpy.ndarray)创建
data = [['Jack', 10], ['Tom', 12], ['Lucy', 13]] columns = ['Name', 'Age'] df_by_list = pd.DataFrame(data, columns=columns) print(df_by_list)
输出: Name Age 0 Jack 10 1 Tome 12 2 Lucy 13
2.基于字典创建
row = { 'Name': ['Jack', 'Tom', 'Lucy'], 'Age': [10, 12, 13] } #row实际上是一个字典 df_by_dict = pd.DataFrame(row) print(df_by_dict)
输出: Name Age 0 Jack 10 1 Tome 12 2 Lucy 13
3.读取csv文件的方式
df = pd.read_csv('city.csv') print(df.head(5))
id name province city 0 101010100 北京 北京市 北京市 1 101010200 海淀 北京市 海淀 2 101010300 朝阳 北京市 朝阳 3 101010400 顺义 北京市 顺义 4 101010500 怀柔 北京市 怀柔
二、查询
1.df直接查询
① 查询一列
names = df['Name'].tolist() print(names)
输出: ['Jack', 'Tom', 'Lucy']
② 查询多列
names = df[['Name','Age']] #注意2层方括号 #注意带df就说明返回值是DataFrame格式 print(names)
Name Age 0 Jack 10 1 Tom 12 2 Lucy 13
③ 条件查询
ages = df[(df['Age'] > 10) & (df['Age'] < 13)] print(ages)
Name Age 1 Tom 12
2.query()方法
① 条件查询
result = df.query('Age > 10 & Age < 13') print(result)
Name Age 1 Tom 12
② 带有变量的查询(用@变量)
names = ['Tom', 'Lily', 'Sam'] result = df.query('Name not in @names') print(result)
Name Age 0 Jack 10 2 Lucy 13
3.查询行索引值
想查Name字段为Tom的行索引:
print(df) index = df[df['Name'] == "Tom"].index.tolist()[0] # 查询索引 print("Tom所在行的索引:", index)
Name Age 0 Jack 10 1 Tom 12 2 Lucy 13 Tom所在行的索引: 1
4.模糊查询 #必须是字符串类型
想对Sdate字段进行模糊查询,查询2023年的数据:
data = [['20201001', 10], ['20201002', 12], ['20201003', 13],['20231003', 13]] columns = ['Sdate', 'type'] df = pd.DataFrame(data, columns=columns) df = df[df['Sdate'].str.contains('2023')] # 模糊查询 print(df)
Sdate type 3 20231003 13
三、增加
1.增加列
① 直接加:在最后一列加新的列
df['Gender'] = ['M', 'M', 'F'] print(df)
Name Age Gender 0 Jack 10 M 1 Tom 12 M 2 Lucy 13 F
② insert方法:可以指定位置加
df.insert(0, 'Gender', ['M', 'M', 'F']) print(df)
Gender Name Age 0 M Jack 10 1 M Tom 12 2 F Lucy 13
2.增加行
① loc函数:增加一行
df.loc[len(df.index)] = ('Lily', 20) #loc[]里面的参数为索引号(以0开始) print(df)
Name Age 0 Jack 10 1 Tom 12 2 Lucy 13 3 Lily 20
如果不加在最后一行,数据将会被替换,例:
df.loc[1] = ('Lily', 20) print(df)
Name Age 0 Jack 10 1 Lily 20 2 Lucy 13
② 增加多行
data1 = [['Lily', 23], ['Sam', 35]] columns1 = ['Name', 'Age'] df1 = pd.DataFrame(data1, columns=columns1) df2 = pd.concat([df, df1], ignore_index=True) print(df2) #1.ignore_index=True 参数表示重新设置索引 #2.append方法即将过时,建议用concat方法 #3.concat方法要求两个df需要有相同的列名
Name Age 0 Jack 10 1 Tom 12 2 Lucy 13 3 Lily 23 4 Sam 35
四、更新(改)
1. 更新整行值
data1 = [['Lily', 23], ['Sam', 35]] columns1 = ['Name', 'Age'] new_df = pd.DataFrame(data1, columns=columns1) df.update(new_df) print(df)
Name Age 0 Lily 23.0 1 Sam 35.0 2 Lucy 13.0
2. 更新某个值
① 通过顺序数字索引修改
df.iloc[0, 1] = 25 # 0表示按顺序数的第一行,1表示第二列 print(df)
Name Age 0 Jack 25 1 Tom 12 2 Lucy 13
② 通过实际设置的索引来修改
loc是根据行名, iloc是根据数字索引
df.loc[0, 'Age'] = 25 # 0表示索引等于0的那一行 print(df)
Name Age 0 Jack 25 1 Tom 12 2 Lucy 13
3.更新某一整列的数值类型
Sdate列由数值型更改为字符串类型
data = [[20201001, 10], [20201002, 12], [20201003, 13]] columns = ['Sdate', 'type'] df = pd.DataFrame(data, columns=columns) print(df) print("Sdate开始类型:",df['Sdate'].dtypes) df['Sdate'] = pd.Series(df['Sdate'], dtype="string") # 更改类型 print("Sdate改变后类型:",df['Sdate'].dtypes)
Sdate type 0 20201001 10 1 20201002 12 2 20201003 13 Sdate开始类型: int64 Sdate改变后类型: string
4.将某一列日期(字符串/object类型)格式进行调整
Sdate列的‘20201001’格式转换成‘2020-10-01’格式
data = [['20201001', 10], ['20201002', 12], ['20201003', 13]] columns = ['Sdate', 'type'] df = pd.DataFrame(data, columns=columns) print(df) # pd.to_datetime(df['Sdate']) 把 Sdate这一列转换为datetime64[ns]时间数据类型 df['Sdate'] = pd.to_datetime(df['Sdate']).dt.strftime('%Y-%m-%d') # 格式化 print(df)
Sdate type 0 20201001 10 1 20201002 12 2 20201003 13 Sdate type 0 2020-10-01 10 1 2020-10-02 12 2 2020-10-03 13
五、删除
1. 删除行
df = df.drop(df[(df['Age'] > 10) & (df['Age'] < 13)].index) print(df)
Name Age 0 Jack 10 2 Lucy 13
2. 删除列
df = df.drop('Age', axis=1) print(df)
Name 0 Jack 1 Tom 2 Lucy
DataFrame.drop (labels=None, axis=0, index=None, columns=None, inplace=False)
labels:要删除的行或列,用列表给出 axis:默认为0,指要删除的是行,删除列时需指定axis为1 index :直接指定要删除的行,删除多行可以使用列表作为参数 columns:直接指定要删除的列,删除多列可以使用列表作为参数 inplace: 默认为False,该删除操作不改变原数据;inplace = True时,改变原数据
六、遍历
Name Age 0 Jack 10 1 Tom 12 2 Lucy 13
for index, row in df.iterrows(): print(index) print(row['Name']) print(row['Age'])
0 Jack 10 1 Tom 12 2 Lucy 13
这里的iterrows()返回值为元组,(index,row),index即为每行的索引值(竖排),row就是一行的所有数据,可通过字段名(列名)获取到;iteritems():按列遍历,将DataFrame的每一列迭代为(列名, Series)对,可以通过row[index]对元素进行访问;row['Name']表示name这一列对应的所有行的元素
七、转换
1、字典和dataFrame的相互转换
①字典转dataFrame
import pandas as pd dic = { 'name':['张三','李四','王二','麻子','小红','小兰','小玉','小强','小娟','小明'], 'num':[802,807,801,803,806,805,808,809,800,804], 'height': [183, 161, 163, 163, 156, 186, 184, 154, 153, 174], 'weight': [87, 60, 71, 74, 45, 50, 47, 67, 49, 70], 'gender': ['男', '男', '男', '男', '女', '女', '女', '男', '女', '男'], 'age': [25, 30, 25, 26, 27, 20, 23, 26, 30, 30] } df=pd.DataFrame(dic) print(df)
②dataFrame转字典
函数DataFrame.to_dict(orient=‘dict’, into=<class ‘dict’>)
参数
orient =‘dict’,是函数默认的,转化后的字典形式:{column(列名) : {index(行名) : value(值)}};
orient =‘list’ ,转化后的字典形式:{column(列名) :{[values](值)}};
orient =‘series’ ,转化后的字典形式:{column(列名) : Series (values) (值)};
orient =‘split’ ,转化后的字典形式:{‘index’ : [index],‘columns’ :[columns],’data‘ : [values]};
orient =‘records’ ,转化后是 list形式:[{column(列名) :value(值)}…{column:value}];
orient =‘index’ ,转化后的字典形式:{index(值) :{column(列名) : value(值)}};
返回
返回值中默认 index 是 key ,其他字段是和 index 对应的 value
1、orient =‘dict’
orient =‘dict’ 是函数默认的,转化后的字典形式: {column(列名) : {index(行名) : value(值)}} #{第一列的列名:{第一行行名:value值,第二行行名,value值,...},…}
dic1 = df.to_dict() print(dic1)
{ 'name': {0: '张三', 1: '李四', 2: '王二', 3: '麻子', 4: '小红', 5: '小兰', 6: '小玉', 7: '小强', 8: '小娟', 9: '小明'}, 'num': {0: 802, 1: 807, 2: 801, 3: 803, 4: 806, 5: 805, 6: 808, 7: 809, 8: 800, 9: 804}, 'height': {0: 183, 1: 161, 2: 163, 3: 163, 4: 156, 5: 186, 6: 184, 7: 154, 8: 153, 9: 174}, 'weight': {0: 87, 1: 60, 2: 71, 3: 74, 4: 45, 5: 50, 6: 47, 7: 67, 8: 49, 9: 70}, 'gender': {0: '男', 1: '男', 2: '男', 3: '男', 4: '女', 5: '女', 6: '女', 7: '男', 8: '女', 9: '男'}, 'age': {0: 25, 1: 30, 2: 25, 3: 26, 4: 27, 5: 20, 6: 23, 7: 26, 8: 30, 9: 30} }
2、 orient =‘list’
orient =‘list’ ,转化后的字典形式:{column(列名) :{[values](值)}};
dic1 = df.to_dict('list') print(dic1)
{ 'name': ['张三', '李四', '王二', '麻子', '小红', '小兰', '小玉', '小强', '小娟', '小明'], 'num': [802, 807, 801, 803, 806, 805, 808, 809, 800, 804], 'height': [183, 161, 163, 163, 156, 186, 184, 154, 153, 174], 'weight': [87, 60, 71, 74, 45, 50, 47, 67, 49, 70], 'gender': ['男', '男', '男', '男', '女', '女', '女', '男', '女', '男'], 'age': [25, 30, 25, 26, 27, 20, 23, 26, 30, 30] }
3、orient =‘series’
orient =‘series’ ,转化后的字典形式:{column(列名) : Series (values) (值)}
dic1 = df.to_dict('series') print(dic1)
{ 'name': 0 张三 1 李四 2 王二 3 麻子 4 小红 5 小兰 6 小玉 7 小强 8 小娟 9 小明 Name: name, dtype: object, 'num': 0 802 1 807 2 801 3 803 4 806 5 805 6 808 7 809 8 800 9 804 Name: num, dtype: int64, 'height': 0 183 1 161 2 163 3 163 4 156 5 186 6 184 7 154 8 153 9 174 Name: height, dtype: int64, 'weight': 0 87 1 60 2 71 3 74 4 45 5 50 6 47 7 67 8 49 9 70 Name: weight, dtype: int64, 'gender': 0 男 1 男 2 男 3 男 4 女 5 女 6 女 7 男 8 女 9 男 Name: gender, dtype: object, 'age': 0 25 1 30 2 25 3 26 4 27 5 20 6 23 7 26 8 30 9 30 Name: age, dtype: int64}
4、orient =‘split’
orient =‘split’ ,转化后的字典形式:{‘index’ : [index],‘columns’ :[columns],’data‘ : [values]}
{'index': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 'columns': ['name', 'num', 'height', 'weight', 'gender', 'age'], 'data': [ ['张三', 802, 183, 87, '男', 25], ['李四', 807, 161, 60, '男', 30], ['王二', 801, 163, 71, '男', 25], ['麻子', 803, 163, 74, '男', 26], ['小红', 806, 156, 45, '女', 27], ['小兰', 805, 186, 50, '女', 20], ['小玉', 808, 184, 47, '女', 23], ['小强', 809, 154, 67, '男', 26], ['小娟', 800, 153, 49, '女', 30], ['小明', 804, 174, 70, '男', 30] ] }
5、orient =‘records’
orient =‘records’ ,转化后是 list形式:[{column(列名) :value(值)}…{column:value}] #每一行的全部数据在数据前加一个列名形成一条数据记录作为列表中的一个元素,直到取出所有行的记录,组成一个列表。
dic1 = df.to_dict('records') print(dic1)
[ {'name': '张三', 'num': 802, 'height': 183, 'weight': 87, 'gender': '男', 'age': 25}, {'name': '李四', 'num': 807, 'height': 161, 'weight': 60, 'gender': '男', 'age': 30}, {'name': '王二', 'num': 801, 'height': 163, 'weight': 71, 'gender': '男', 'age': 25}, {'name': '麻子', 'num': 803, 'height': 163, 'weight': 74, 'gender': '男', 'age': 26}, {'name': '小红', 'num': 806, 'height': 156, 'weight': 45, 'gender': '女', 'age': 27}, {'name': '小兰', 'num': 805, 'height': 186, 'weight': 50, 'gender': '女', 'age': 20}, {'name': '小玉', 'num': 808, 'height': 184, 'weight': 47, 'gender': '女', 'age': 23}, {'name': '小强', 'num': 809, 'height': 154, 'weight': 67, 'gender': '男', 'age': 26}, {'name': '小娟', 'num': 800, 'height': 153, 'weight': 49, 'gender': '女', 'age': 30}, {'name': '小明', 'num': 804, 'height': 174, 'weight': 70, 'gender': '男', 'age': 30} ]
6、orient =‘index’
orient =‘index’ ,转化后的字典形式:{index(值) :{column(列名) : value(值)}}
dic1 = df.to_dict('index') print(dic1)
{ 0: {'name': '张三', 'num': 802, 'height': 183, 'weight': 87, 'gender': '男', 'age': 25}, 1: {'name': '李四', 'num': 807, 'height': 161, 'weight': 60, 'gender': '男', 'age': 30}, 2: {'name': '王二', 'num': 801, 'height': 163, 'weight': 71, 'gender': '男', 'age': 25}, 3: {'name': '麻子', 'num': 803, 'height': 163, 'weight': 74, 'gender': '男', 'age': 26}, 4: {'name': '小红', 'num': 806, 'height': 156, 'weight': 45, 'gender': '女', 'age': 27}, 5: {'name': '小兰', 'num': 805, 'height': 186, 'weight': 50, 'gender': '女', 'age': 20}, 6: {'name': '小玉', 'num': 808, 'height': 184, 'weight': 47, 'gender': '女', 'age': 23}, 7: {'name': '小强', 'num': 809, 'height': 154, 'weight': 67, 'gender': '男', 'age': 26}, 8: {'name': '小娟', 'num': 800, 'height': 153, 'weight': 49, 'gender': '女', 'age': 30}, 9: {'name': '小明', 'num': 804, 'height': 174, 'weight': 70, 'gender': '男', 'age': 30} }
7、指定列为key生成字典的实现步骤(按行)
1、set_index用于将想设置为key的列设置为数据框索引
df.set_index("name", drop=True, inplace=True) # 其中 drop=True去重,inplace=True在原数据上更改
2、使用orient=index参数将索引用作字典键
dictionary = df.to_dict(orient="index") print(dictionary)
{ '张三': {'num': 802, 'height': 183, 'weight': 87, 'gender': '男', 'age': 25}, '李四': {'num': 807, 'height': 161, 'weight': 60, 'gender': '男', 'age': 30}, '王二': {'num': 801, 'height': 163, 'weight': 71, 'gender': '男', 'age': 25}, '麻子': {'num': 803, 'height': 163, 'weight': 74, 'gender': '男', 'age': 26}, '小红': {'num': 806, 'height': 156, 'weight': 45, 'gender': '女', 'age': 27}, '小兰': {'num': 805, 'height': 186, 'weight': 50, 'gender': '女', 'age': 20}, '小玉': {'num': 808, 'height': 184, 'weight': 47, 'gender': '女', 'age': 23}, '小强': {'num': 809, 'height': 154, 'weight': 67, 'gender': '男', 'age': 26}, '小娟': {'num': 800, 'height': 153, 'weight': 49, 'gender': '女', 'age': 30}, '小明': {'num': 804, 'height': 174, 'weight': 70, 'gender': '男', 'age': 30} }
3、将步骤1、2合起来写也可以,这里不修改源数据
dictionary = df.set_index("name", drop=True).to_dict(orient="index")
8、指定列为key,value生成字典的实现
1、指定一个列为key,一列为value
dictionary = df.set_index("name")["num"].to_dict() print(dictionary)
{ '张三': 802, '李四': 807, '王二': 801, '麻子': 803, '小红': 806, '小兰': 805, '小玉': 808, '小强': 809, '小娟': 800, '小明': 804 }
2、指定多个列为key,一列为value
dictionary = df.set_index(["name","num"])["weight"].to_dict() print(dictionary)
{ ('张三', 802): 87, ('李四', 807): 60, ('王二', 801): 71, ('麻子', 803): 74, ('小红', 806): 45, ('小兰', 805): 50, ('小玉', 808): 47, ('小强', 809): 67, ('小娟', 800): 49, ('小明', 804): 70 }
3、指定一个列为key,多列为value
方法1(速度慢)
dictionary = {c0:[c1,c2] for c0,c1,c2 in zip(df['name'],df['num'],df['weight'])} print(dictionary)
{ '张三': [802, 87], '李四': [807, 60], '王二': [801, 71], '麻子': [803, 74], '小红': [806, 45], '小兰': [805, 50], '小玉': [808, 47], '小强': [809, 67], '小娟': [800, 49], '小明': [804, 70] }
方法2(速度快)
dictionary = df[["name",'num','weight']].set_index('name').T.to_dict('list') print(dictionary)
{ '张三': [802, 87], '李四': [807, 60], '王二': [801, 71], '麻子': [803, 74], '小红': [806, 45], '小兰': [805, 50], '小玉': [808, 47], '小强': [809, 67], '小娟': [800, 49], '小明': [804, 70] }
4、 指定多列为key,多列为value
dictionary = df[["name",'num','weight',"age"]].set_index(['name','num']).T.to_dict('list') print(dictionary)
{ ('张三', 802): [87, 25], ('李四', 807): [60, 30], ('王二', 801): [71, 25], ('麻子', 803): [74, 26], ('小红', 806): [45, 27], ('小兰', 805): [50, 20], ('小玉', 808): [47, 23], ('小强', 809): [67, 26], ('小娟', 800): [49, 30], ('小明', 804): [70, 30] }
2、数据类型转换
df = pd.read_csv('energy.csv', encoding='gb2312') print(df.dtypes) df['能量值'] = df['能量值'].astype(object) print("=====================================") print(df.dtypes)
日期 object 能量值 int64 电量值 float64 dtype: object ===================================== 日期 object 能量值 object 电量值 float64 dtype: object
3、把Nan值转换成None值
原因:pandas中的空值是NaN表示的,如果插入数据库中,必须将NaN转换成None值,否则会报错
df = pd.read_csv('energy.csv', encoding='gb2312') print(df) # df.astype(object) ==> DataFram : 先把表中所有类型改为object # df.where(条件式,值) ==> DataFram: 在满足条件式的位置保留原值,在不满足条件的位置填充自设的值 # pd.notnull(df) ==> DataFram: 返回一个布尔类型的df,NaN位置为False,其余位置为True print("=====================================") df = df.astype(object).where(pd.notnull(df), None) print(df)
日期 能量值 电量值 0 2020-06-06 2900 NaN 1 2020-06-07 3300 0.0 2 2020-06-08 666 666.0 ===================================== 日期 能量值 电量值 0 2020-06-06 2900 None 1 2020-06-07 3300 0.0 2 2020-06-08 666 666.0
八、其他
1、去除有Nan值的行
df = pd.read_csv('energy.csv', encoding='gb2312') print(df) print("==========================================") result = df.drop(df[df.isnull().T.any()].index) print(result)
日期 能量值 电量值 0 2020-06-06 2900 NaN 1 2020-06-07 3300 0.0 2 2020-06-08 666 666.0 ========================================== 日期 能量值 电量值 1 2020-06-07 3300 0.0 2 2020-06-08 666 666.0
df = pd.read_csv('energy.csv', encoding='gb2312') print(df) print("==========================================") print("df.isnull():") print(df.isnull()) print("==========================================") print("df.isnull().T:") print(df.isnull().T) print("==========================================") print("df.isnull().T.any():") print(df.isnull().T.any()) # any()==> Series: 返回任何元素是否为真(可能在轴上)。 print("==========================================") print("df[df.isnull().T.any()]:") print(df[df.isnull().T.any()]) print("==========================================") print("df[df.isnull().T.any()].index:") print(df[df.isnull().T.any()].index)
日期 能量值 电量值 0 2020-06-06 2900 NaN 1 2020-06-07 3300 0.0 2 2020-06-08 666 666.0 ========================================== df.isnull(): 日期 能量值 电量值 0 False False True 1 False False False 2 False False False ========================================== df.isnull().T: 0 1 2 日期 False False False 能量值 False False False 电量值 True False False ========================================== df.isnull().T.any(): 0 True 1 False 2 False dtype: bool ========================================== df[df.isnull().T.any()]: 日期 能量值 电量值 0 2020-06-06 2900 NaN ========================================== df[df.isnull().T.any()].index: Int64Index([0], dtype='int64')
2、join操作
df1 = pd.read_csv('energy.csv', encoding='gb2312') df2 = pd.read_csv('energy.csv', encoding='gb2312') result = pd.merge(df1, df2, how='left', on=['日期']) # df1 left join df2 print(result)
日期 能量值_x 电量值_x 能量值_y 电量值_y 0 2020-06-06 2900 NaN 2900 NaN 1 2020-06-07 3300 0.0 3300 0.0 2 2020-06-08 666 666.0 666 666.0