pandas常用方法

一、提要

pandas对于处理表格类数据来说是非常方便的模块,同时也是做数据分析绕不开的第三方库。这里将工作中常用到的各种处理方法记录下来

二、常用方法

接下来的以 df 表示我们要处理的 dataframe 表格数据

1、取值

# 循环遍历取值
for i in range(len(df)):
   yh_bm = df.iloc[i]['yh_bm']
   cp_name = df.iloc[i]['cp_name']
可以通过循环将该表所有编码,名称全部依次取出


# 下面这两个写法效果相同,都是取第几行第几列的那个值
jz_date = df.iloc[i][num]
jz_date = df.iloc[i,num]


# 取行名为 合计,列名为 穿透前金额 的值
df = df[df.values == '合计']['穿透前金额'].values[0]

# 定位取值
cp_name = df.loc[df['yh_bm'] =='345634A', 'cp_name'].values[0]
print(cp_name)
意思是取 yh_bm 这一列中,值为 345634A 的这一行中 cp_name 的值。其中values是将所有符合条件的值都取出来,列表形式。values[0]即是取第一个符合条件的值。

2、切片

# 总行数
z_ls=df.shape[0]
# 总列数
con1 = df.shape[1]
# 获取前10行
con=df.loc[:10]
# 取所有行中第一到二列
data=df.iloc[:,1:2]

3、删除Pandas DataFrame中的某些字段

import pandas as pd

# 创建一个示例DataFrame
data = {'A': [1, 2, 3],
        'B': [4, 5, 6],
        'C': [7, 8, 9]}
df = pd.DataFrame(data)

# 删除字段B和C
df = df.drop(['B', 'C'], axis=1)

# 打印结果
print(df)

   A
0  1
1  2
2  3

4、获取索引

# 取出所有值为‘估值日’对应的索引行,列表形式展示
df = df[df.values == '估值日'].index.values.tolist()

5、判断并赋值

# 查询并赋值(如果id字段为'',产品状态赋值为新增)
df.loc[df['id'] == '', '产品状态'] = '新增'
# 如果id字段为'',产品状态赋值为新增,否则产品状态赋值为已存在。
df['产品状态'] = df.id.apply(lambda x: '新增' if x=='' else '已存在')
# 将 实际到期日<库内实际到期日 的各行数据,是否提前终止 字段值改为是
df.loc[df['实际到期日'] < df['库内实际到期日'], '是否提前终止'] = '是'
# 将 净值日期大于等于2022/8/24并且beizhu字段值为1的数据, 净值分配类型 字段值改为 扣除超额收益
df.loc[(df['净值日期'] >= datetime.datetime(2022, 8, 24)) & (df['beizhu'] == '1'), '净值分配类型'] = '扣除超额收益'

6、取某字段内包含某字段值的数据

# 取产品全称字段内包含备注字段值的数据
df=df[df.apply(lambda x: x.beizhu in x.产品全称, axis=1)]

输入:
产品全称	beizhu	
中国	       中	
中国	       国	
中国	       年	

输出:
  产品全称 beizhu  
0   中国      中  
1   中国      国  

7、日期格式处理

# 净值日期减一天
df['净值日期'] = pd.to_datetime(df['净值日期'], errors='coerce') - pd.Timedelta('1 days')

# pandas日期相减,算出投资期限
df = df['投资结束日'].apply(pd.to_datetime) - df['投资开始日'].apply(pd.to_datetime)
df['投资期限'] = df.apply(lambda x: x.days)

# 如取最新的一百条成立公告(通过创建日期、公告日期排序,取前100条)ascending决定正序倒序
df = df.sort_values(by=['create_time', 'announcement_date'], ascending=False)[:100]

# 将trading_date列转为字符串类型
df['trading_date'] = df['trading_date'].astype(str)
# 取trading_date列中时间大于等于某个日期的行
con1= df['trading_date'] >= xz_start_date
# 取trading_date列中时间小于某个日期的行
con2 = df['trading_date'] < xz_end_date

# 将trading_date、xz_start_date字段转为时间格式,转换失败的填充null
df['trading_date'] = pd.to_datetime(df['trading_date'], errors='coerce')
df['xz_start_date'] = pd.to_datetime(df['xz_start_date'], errors='coerce')
# 取日期列 xz_start_date < trading_date 的表格内容
df=df[df['xz_start_date']<df['trading_date']]

8、去重

# 去重 subset决定通过哪些字段去重 keep表示保留哪一条(first,last是表示第一条或最后一条。而false则表示不保留) inplace表示是否改变源表
paimingdata1.drop_duplicates(subset=['产品id', '报告期', '持仓资产名称', '资产规模', '资产占比'], keep='first',inplace=True)

9、模糊取值

# 取某字段下存在某些字符的df
df = df[df['title'].str.contains('2021年第4季度报告|投资非标资产情况公告')]
即取title列中,值包含‘2021年第4季度报告’或‘投资非标资产情况公告’的表格内容
例:
输入
title	                 date
中国银行2021年第4季度报告	   2020/11/11
中国银行投资非标资产情况公告	2020/11/12
中国银行净值报告	        2020/11/13

输出
title	                 date
中国银行2021年第4季度报告	   2020/11/11
中国银行投资非标资产情况公告	2020/11/12

10、从一个表里删除另一个表某字段已包含的表格

# ~表示取反 即不取 df_A产品全称字段 内包含 df_B产品全称字段值的内容
df_A = df_A[~df_A['产品全称'].isin(df_B['产品全称'])]
语言不好描述,看例子:

输入df_A:
产品全称	      date
工银理财·鑫尊享	2023/3/3
工银理财·全鑫权益	2023/3/4
工银理财·全球臻选	2023/3/5
工银理财·"全鑫权益	 2023/3/6
工银理财·核心优选私银	2023/3/7
工银理财·恒睿睿益	 2023/3/8
工银理财·A	        2023/3/9
工银理财·B	        2023/3/10
工银理财·C	        2023/3/11
工银理财            2023/3/12

输入df_B:
产品全称	      date
工银理财·鑫尊享	2023/3/3
工银理财·全鑫权益	2023/3/4
工银理财·全球臻选	2023/3/5
工银理财·"全鑫权益	 2023/3/6
工银理财·核心优选私银	2023/3/7
工银理财·恒睿睿益	 2023/3/8


输出:
     产品全称     date
6  工银理财·A     2023-03-09
7  工银理财·B     2023-03-10
8  工银理财·C     2023-03-11
9  工银理财       2023-03-12

11、填充、平移

# 向上填充,可选择method = 'bfill‘
# 向下填充,可选择method = 'ffill‘
df['产品名称'] = df['产品名称'].fillna(method='ffill')
df['融资客户名称'] = df['融资客户名称'].fillna(method='ffill')

#-1 向上平移一格
# 1 向下平移一格
df['产品名称_'] = df['产品名称'].shift(-1)
df['融资客户名称_'] =df['融资客户名称'].shift(1)

12、分组填充

# 即 通过'净值日期'和'银行产品编码'分组,上下填充'7日年化收益率'和'万份收益'的值
jzdata2[['7日年化收益率', '万份收益']] = jzdata2.groupby(['净值日期', '银行产品编码'])[['7日年化收益率', '万份收益']].ffill()
jzdata2[['7日年化收益率', '万份收益']] = jzdata2.groupby(['净值日期', '银行产品编码'])[['7日年化收益率', '万份收益']].bfill()

13、循环截取

在这里插入图片描述

当遇到上面这个表格内容的时候,该怎么将这一个表分成4个表呢

# 重置索引
leibie_df = df.reset_index(drop=True)
# 取出 产品全称 所在的所有索引
leibie_df_index = leibie_df[leibie_df.values == '产品全称'].index.values.tolist()
print(leibie_df_index)
# 获取索引数量
len_list = len(leibie_df_index)
num = 0
# 循环索引数量次数(有几个索引就循环几次,即有几个产品全称,就循环几次)
for x in range(len_list):
    num += 1
    # 如果此时循环次数==索引数量-1 即最后一次循环
    if x == len_list - 1:
        # 截取出来的小表格范围为 最后一个产品全称 所在的索引行 到最后
        result_df = df[leibie_df_index[x]:]
    else:
        y = x + 1
        # 截取出来的小表格范围为 一个产品全称 所在的索引行 到 另一个产品全称 所在的索引行
        result_df = df[leibie_df_index[x]:leibie_df_index[y]]
     # 将取出来的小表格重置索引
     result_df=leibie_df1.reset_index(drop=True)

14、其他常用方法

# 取反(剔除)
# 剔除 产品ID值为1256249 并且 净值日期为2020-05-28的数据
df = df[~(df['产品ID'].isin([1256249]) & df['净值日期'].isin(['2020-05-28']))]

# 删除净值日期列是空值的行
df.dropna(subset=['净值日期'], inplace=True)
# 通过取反 剔除'产品全称'里是空值的行
df=df[~df['产品全称'].isin([''])]

# 重置行索引
df = df.reset_index(drop=True)

#重置列索引
df=df.T.reset_index(drop=True).T

# 删除name、age列中,【任一列值为空】的行;
df.dropna(subset=['name', 'age'],
          axis=0, # axis=0表示删除行;
          how='any', # how=any表示若任一列出现空值,就删掉该行
          inplace=True # inplace=True表示在原df上进行修改;
          )
# 删除name、age列中,二者都为空的行。
# 删除都为空的行,还是删除任一列值为空的行,使用参数how来控制
df.dropna(subset=['name', 'age'],
          axis=0,
          how='all', # how='all'表示指定列的值都为空,就删掉该行
          inplace=True)

# 处理重复列名(相同列名,对应值不同,则将列名改名)
column_names = df.columns.values
column_names[2] = 'Changed'
df.columns = column_names
print(column_names)
# 删除重复列名(几列值完全相同)
df = df[df.columns].T.drop_duplicates().T

#处理特殊字符  如\n \r 空格
df = df.applymap((lambda x: "".join(x.split()) if type(x) is str else x))

# 批量模糊匹配剔除
# 剔除'项目名称'字段中包含'', '-', '—', '-', '0', '0.0', '0.00'的数据
df = df[~df['项目名称'].isin(['', '-', '—', '-', '0', '0.0', '0.00'])]

# 修改列名
df = df.rename(columns={'份额净值': '当日账面净值', '日期': '净值日期', '七日年化收益率': '7日年化收益率'})
或
df.rename(columns={'份额净值': '当日账面净值', '日期': '净值日期', '七日年化收益率': '7日年化收益率'},inplace=Ture)

house_info = pd.read_csv('house_info.csv')
1:取行的操作:
house_info.loc[3:6]类似于python的切片操作

2:取列操作:
house_info['price']  这是读取csv文件时默认的第一行索引

3:取两列
house_info[['price','tradetypename']] 取多个列也是同理的,注意里面是一个list的列表,不然会报错误;

4:增加列:
house_Info['adress_new']=list([.....])  跟字典的操作有点类似;

5:对某一列除以他的最大值,这样可以得到一个01的数值范围,也就是一个简易的归一化操作;
house_info['price']/house_info['price'].max()

6:对列进行排序操作:
qianshi_df.sort_values(by=['资产占比排名'], inplace=True, ascending=True) 这里的inplace表示再排序的时候是否生成一个新的dataframe 结构,ascending=true表示升序,默认也是升序;还有一点应该注意的是:对于缺省值,(Nan)排序的时候会把他排在末尾;

7:如何获取缺省值,:
column_null = pd.isnull(column)
column_is_null_true = column[column_null]



# pandas对列求和
import pandas as pd
datas = [
        {'学生': '小红', '语文': None, '数学': 89.5, '英语': 99, '物理':70, 'active': False},
        {'学生': '小明', '语文': 88, '数学': 89.5, '英语': 99, '物理':70, 'active': True},
        {'学生': '小玉', '语文': 78.5, '数学': 79.5, '英语': 92.5, '物理':78, 'active': True},
        {'学生': '小刚', '语文': 60, '数学': 59.5, '英语': 87, '物理':None, 'active': False},
     ]
sum = dict(pd.DataFrame(datas).drop(columns=['学生']).fillna(0).apply(lambda x: round(x.sum(), 2) if all(isinstance(d, (int, float)) and not isinstance(d, bool) for d in x) else ''))
print(sum)
输出:
{'语文': 226.5, '数学': 318.0, '英语': 377.5, '物理': 218.0, 'active': ''}
先将数据转成二维数组,然后排除掉不想求和的列,使用0填充nan值,然后对每一列进行遍历,判断每一个元素是否为intfloat型,并且不为布尔型,然后使用sum函数对列求和。
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值