Excel卡死?是时候让Pandas登场了
兄弟们好啊。
不知道你们有没有这样的经历——用Excel打开一个几十万行的数据文件,等了10分钟还没打开,或者直接电脑卡死了。
别慌。今天教你的Pandas,就是来处理这种大数据的神器。千万级数据不在话下,让你的Excel看起来像个玩具。
数据结构得先搞懂,两核心:Series和DataFrame
import pandas as pd
import numpy as np
# Series - 就是一维数组/列表
s = pd.Series([1, 3, 5, np.nan, 6, 8])
print(s)
# DataFrame - 就是表格,二维的
df = pd.DataFrame({
'姓名': ['张三', '李四', '王五', '赵六'],
'年龄': [25, 30, 35, 40],
'工资': [8000, 12000, 15000, 20000]
})
print(df)
读取数据,5种常见格式一键搞定
# CSV文件 - 最常用
df = pd.read_csv('data.csv')
# Excel文件
df = pd.read_excel('data.xlsx', sheet_name='Sheet1')
# JSON文件
df = pd.read_json('data.json')
# SQL数据库
from sqlalchemy import create_engine
engine = create_engine('sqlite:///mydb.db')
df = pd.read_sql('SELECT * FROM users', engine)
# 从URL直接读取
df = pd.read_csv('https://example.com/data.csv')
千万级数据处理,才是重头戏
一般人会说Pandas慢,那是他们不会优化。
import pandas as pd
# 基础操作
df = pd.read_csv('big_data.csv')
# 数据类型优化 - 省内存
df['age'] = df['age'].astype('int32')
df['salary'] = df['salary'].astype('float32')
# 只读取需要的列 - 快到飞起
df = pd.read_csv('big_data.csv', usecols=['name', 'age', 'salary'])
# 分块读取 - 内存不够的救星
chunks = pd.read_csv('big_data.csv', chunksize=100000)
for chunk in chunks:
process(chunk)
筛选数据,一行代码搞定
# 基础筛选
df[df['age'] > 25]
# 多条件筛选
df[(df['age'] > 25) & (df['salary'] > 10000)]
df[(df['age'] < 25) | (df['salary'] > 20000)]
# 字符串筛选
df[df['name'].str.contains('张')]
# 高级筛选 - query方法
df.query('age > 25 and salary > 10000')
数据清洗,这些坑你肯定遇到过
# 处理缺失值
df.dropna()
df.fillna(0)
df['age'].fillna(df['age'].mean())
# 去除重复
df.drop_duplicates(subset=['name', 'age'])
# 异常值处理
df = df[df['salary'] < 100000]
df = df[df['age'].between(18, 65)]
# 字符串处理
df['name'] = df['name'].str.strip()
df['phone'] = df['phone'].str.replace('-', '')
分组聚合,数据分析的精髓
# 简单分组统计
df.groupby('department')['salary'].mean()
# 复杂分组聚合
df.groupby('department').agg({
'salary': ['mean', 'max', 'min'],
'age': 'mean',
'name': 'count'
})
# 多级索引分组
df.groupby(['department', 'level'])['salary'].agg(['mean', 'count'])
# 实战:统计每个城市的销售情况
sales_df.groupby(['city', 'product']).agg({
'revenue': 'sum',
'quantity': 'sum',
'order_id': 'count'
}).reset_index()
数据合并,join其实很简单
# 合并两个DataFrame
pd.merge(df1, df2, on='user_id')
# 其他连接方式
pd.merge(df1, df2, on='user_id', how='left')
pd.merge(df1, df2, on='user_id', how='right')
pd.merge(df1, df2, on='user_id', how='outer')
# 追加行
pd.concat([df1, df2], ignore_index=True)
# 追加列
pd.concat([df1, df3], axis=1)
性能优化,这几招让你的代码快10倍
# 1. 用agg而不是apply
# 慢
df['new_col'] = df.apply(lambda x: x['a'] + x['b'], axis=1)
# 快
df['new_col'] = df['a'] + df['b']
# 2. 用向量化操作,别用循环
# 慢
for i in range(len(df)):
df.loc[i, 'new'] = df.loc[i, 'a'] * 2
# 快
df['new'] = df['a'] * 2
# 3. 用query代替布尔索引
df[(df['a'] > 1) & (df['b'] < 10)]
df.query('a > 1 and b < 10')
导出数据,各种格式随便转
# 保存为CSV
df.to_csv('result.csv', index=False)
# 保存为Excel
df.to_excel('result.xlsx', sheet_name='数据', index=False)
# 保存为JSON
df.to_json('result.json', force_ascii=False, orient='records')
# 保存为Parquet
df.to_parquet('result.parquet')
# 保存为Pickle
df.to_pickle('result.pkl')