项目概况

常用函数

2026-01-295 min read数据处理
pandas

Pandas

读取Excel

读取文件,解析sheet名为下面的表格,跳过最后2行

python
1rateTable = pd.ExcelFile('rate.xlsx').parse(sheet_name='即期汇率', skipfooter=2)

数据过滤

重新赋值,只保留指定的日期

python
1rateTable = rateTable[rateTable['日期'] == '2023-04-03']

宽数据转长数据

主要用户存储到mysql中。

python
1rateTable = rateTable[rateTable['日期'] == '2023-04-03'] 2# 日期 USD/CNY EUR/CNY ... CNY/TRY CNY/MXN CNY/THB 3# 18 2023-04-03 6.8805 7.4381 ... 2.78943 2.6205 4.9746 4print(rateTable) 5 6# melt() 函数,将一个宽表格转换为一个长表格,具体解释如下: 7# frame pd对象 8# id_vars 不变的列,就是将宽数据按照一个维度转换成长数据 9# value_vars 那一列的数据,要转换为行数据 10# var_name 对values_vars数据新命名一个列名 11# value_name 对value_vars的数值新命名一个列名 12newTable = pd.melt(frame=rateTable, id_vars=['日期'], value_vars=['USD/CNY', 'CNY/TRY'], var_name='currency', 13 value_name="exchange_rate") 14# 日期 currency exchange_rate 15# 0 2023-04-03 USD/CNY 6.88050 16# 1 2023-04-03 CNY/TRY 2.78943 17print(newTable)

日期列转换

python
1# Name: 日期, dtype: object 2print(newTable['日期']) 3 4newTable['日期'] = pd.to_datetime(newTable['日期']) 5# Name: 日期, dtype: datetime64[ns] 6print(newTable['日期'])

获取最大日期

python
1max_date = max(newTable['日期']) 2# 2023-04-28 00:00:00 3print(max_date)

条件过滤

如果币种中包含CNY,~取反

str.replace() 函数的参数说明如下:

  • pat:要替换的模式,可以是字符串或正则表达式,这里使用了正则表达式 cny|d*|/;
  • regex:指示 pat 是否为正则表达式,这里设置为 True;
  • repl:用于替换 pat 匹配的字符串,这里设置为空字符串 "";
  • flags:正则表达式的匹配标志,这里设置为 re.IGNORECASE,表示不区分大小写。
python
1newTable = newTable[~newTable['currency'].str.startswith(pat='CNY')]

深复制

当我们需要对原数据进行增加列时候要深复制一个,否则会报错。

python
1newTable_01 = newTable.copy(deep=True)

增加列

python
1newTable_01['year'] = '2023' 2newTable_01['month'] = '04' 3newTable_01['nature'] = '月末即期汇率'

列重命名

python
1# 日期 currency exchange_rate year month nature 2# 0 2023-04-28 USD/CNY 6.92400 2023 04 月末即期汇率 3# 19 2023-04-28 EUR/CNY 7.63610 2023 04 月末即期汇率 4# 38 2023-04-28 100JPY/CNY 5.17230 2023 04 月末即期汇率 5newTable_01.rename(columns={"日期": "remark", "currency": "subsidiary_currency"}, inplace=True) 6# remark subsidiary_currency exchange_rate year month nature 7# 0 2023-04-28 USD/CNY 6.92400 2023 04 月末即期汇率 8# 19 2023-04-28 EUR/CNY 7.63610 2023 04 月末即期汇率 9# 38 2023-04-28 100JPY/CNY 5.17230 2023 04 月末即期汇率 10# 57 2023-04-28 HKD/CNY 0.88206 2023 04 月末即期汇率

更新到mysql中

python
1from sqlalchemy import create_engine 2import pyodbc 3import numpy as np 4import re 5import pandas as pd 6engine = create_engine('mysql+pymysql://root:123456@127.0.0.1/ods?charset=utf8') 7 8# 删除当前账期的数据,所以可以重复执行 9sql = "delete from external_rate where year={y} and month={m}".format(y=year,m=month) 10engine.execute(sql) 11 12# 更新到数据库 13exchange_rate.to_sql(name="external_rate",if_exists="append",con=engine,index=False)

追加

python
1import pandas as pd 2 3df1 = pd.DataFrame({'A': [1, 2], 'B': [3, 4]}) 4df2 = pd.DataFrame({'A': [5, 6], 'B': [7, 8]}) 5 6# 不使用ignore_index参数 7df = df1.append(df2) 8print(df) 9 10# 使用ignore_index参数 11df = df1.append(df2, ignore_index=True) 12print(df)

使用ignore_index=True参数可以忽略所有原来的索引,而使用一个新的索引。这样做可以确保合并后的DataFrame对象具有唯一的索引,并且索引值是从0开始的连续整数。

text
1# 不使用ignore_index参数 2 A B 30 1 3 41 2 4 50 5 7 61 6 8 7 8# 使用ignore_index参数 9 A B 100 1 3 111 2 4 122 5 7 133 6 8

列范围筛选

python
1finance_period = ['2023年度3月', '调整财政年度 2023'] 2xsz = xsz[xsz['account_period'].isin(finance_period)]

apply 函数

python
1data = {'Alice': [10000, 20000, 15000, 18000], 'Bob': [12000, 18000, 20000, 9000], 2 'Charlie': [8000, 12000, 15000, 10000]} 3df = pd.DataFrame(data, index=['Beijing', 'Shanghai', 'Guangzhou', 'Shenzhen']) 4print(df) 5# Alice Bob Charlie 6# Beijing 10000 12000 8000 7# Shanghai 20000 18000 12000 8# Guangzhou 15000 20000 15000 9# Shenzhen 18000 9000 10000
  • 根据列聚合
python
1# 对每一列进行求和操作 2total_income_by_person = df.apply(sum, axis=0) 3print(total_income_by_person) 4# Alice 63000(10000 + 20000 + 15000 + 18000) 5# Bob 59000 6# Charlie 45000
  • 根据行处理
python
1# 对每一行进行求和操作 2total_income_by_city = df.apply(sum, axis=1) 3print(total_income_by_city) 4# Beijing 30000 5# Shanghai 50000 6# Guangzhou 50000 7# Shenzhen 37000

数据合并

python
1def concat_dataframes(*dataframes, ignore_index=True): 2 """ 3 合并多个 DataFrame 并返回合并后的结果。 4 5 参数: 6 *dataframes (pd.DataFrame): 要合并的多个 DataFrame。 7 ignore_index (bool): 是否重置索引,默认为 True。 8 9 返回: 10 pd.DataFrame: 合并后的结果 DataFrame。 11 """ 12 result = pd.concat(dataframes, ignore_index=ignore_index) 13 return result

Mysql连接

python
1from sqlalchemy import create_engine 2def reportEngine(): 3 return create_engine("mssql+pyodbc://root:123#@127.0.0.1:3306/data?driver=SQL+Server", 4 echo=False, echo_pool=False)

VBA + Excel

python
1import xlwings as xw 2def exeExcelVba(vba_excel_path, current_excel_path, vba_method_name): 3 ''' 4 执行 vba 脚本优化输出文件样式 5 :param vba_excel_path: 6 :param current_excel_path: 7 :param vba_method_name: 8 :return: 9 ''' 10 app = xw.App(visible=True, add_book=False) 11 vba = app.books.open(vba_excel_path, read_only=False) 12 # reportSet 13 bk = app.books.open(current_excel_path, read_only=False) 14 bk.activate() 15 vba.macro(vba_method_name)() 16 bk.save() 17 bk.close() 18 vba.close() 19 app.quit()

发邮件

python
1import smtplib 2from email.mime.text import MIMEText 3from email.utils import formataddr 4from email.mime.text import MIMEText 5from email.mime.multipart import MIMEMultipart 6 7 8def send_email(email_name: str, 9 passwd: str, 10 msg_to: list, 11 subject: str, 12 content: str, 13 acc_to: list = None, 14 att_file: list = None, 15 from_name: str = None) -> bool: 16 ''' 17 发送邮件方法: 18 :param email_name:发送者邮件地址 19 :param passwd:发送者邮箱密码 20 :param msg_to:收件人地址列表,参数类型是列表 21 :param subject:邮件主题,字符串类型 22 :param content:邮件文本内容,字符串类型 23 :param acc_to:抄送人地址列表,参数类型是列表,默认值是None 24 :param att_file:附件列表,参数类型是列表,默认值为None 25 :param from_name: 显示发件人的名字,字符串类型,默认值为None 26 :return bool:成功返回True,失败返回False 27 ''' 28 # 这个是可以发送附件并且包含多样式的内容的对象 29 msg = MIMEMultipart() 30 # 邮件正文内容 31 # msg.attach(MIMEText(content)) 32 msg.attach(MIMEText(content, 'html', 'utf-8')) 33 34 # 设置邮件 35 msg['Subject'] = subject 36 msg['From'] = from_name 37 msg['To'] = ';'.join(msg_to) 38 msg['Cc'] = ';'.join(acc_to) 39 40 # 判断是否包含附件 41 if len(att_file) > 0: 42 for file in att_file: 43 print(file) 44 att = MIMEText(open(file, 'rb').read(), 'plain', 'utf-8') 45 att['Content-Type'] = 'application/octet-stream' 46 att.add_header("Content-Disposition", 'attachment', filename=('gbk', "", file)) 47 msg.attach(att) 48 49 # 连接邮件服务器 50 s = smtplib.SMTP('smtp.partner.outlook.cn', 587) 51 s.ehlo() # 向邮箱发送SMTP 'ehlo' 命令 52 s.starttls() 53 # 登陆我的邮箱 54 s.login(email_name, passwd) 55 # 发送邮箱 56 s.sendmail(email_name, msg_to + acc_to, msg.as_string()) 57 print("发送成功")

Pandas 列

python
1 2from IPython.display import display, HTML 3def columns(df: DataFrame): 4 colorPrint(df.columns, 'red') 5 # 提取列名 6 columns = df.columns 7 # 创建字典,将列名和数据类型存储起来 8 column_data_types = {} 9 for column in columns: 10 column_data_types[column] = str(df[column].dtype) 11 # 转换为DataFrame 12 dt_df = pd.DataFrame(list(column_data_types.items()), columns=['列名称', '列类型']) 13 # 输出表格 14 display(dt_df)

深拷贝

python
1def deepCopy(pd: DataFrame): 2 ''' 3 深拷贝 4 :param pd: 5 :return: 6 ''' 7 return pd.copy(deep=True)

年月

python
1from datetime import datetime 2# 获取当前时间 3def currentDate(): 4 # 获取当前时间 5 current_time = datetime.now() 6 # 格式化当前时间 7 return current_time.strftime("%Y-%m-%d %H:%M:%S")

去重函数

python
1def duplicated(df: DataFrame, cols: []): 2 ''' 3 查询 Pandas 中的重复数据 4 :param df: 5 :param cols: 6 :return: 7 ''' 8 duplicated_rows = df[df.duplicated(subset=cols, keep=False)] 9 colorBoldPrint('去重列:{} === 重复行数:{}'.format(','.join(cols), len(duplicated_rows)), 'blue') 10 # 打印出重复的行 11 print(duplicated_rows.head(3))