在Python数据分析领域,NumPy、Pandas和xarray是最核心的三个库。本文将详细介绍它们的功能、用法和区别,并提供大量实用代码示例。
NumPy是Python科学计算的基础包,提供了高性能的多维数组对象和各种计算工具。
import numpy as np
# 创建数组
arr1 = np.array([1, 2, 3, 4]) # 一维数组
arr2 = np.array([[1, 2], [3, 4]]) # 二维数组
arr3 = np.zeros((2, 3)) # 全零数组
arr4 = np.ones((3, 2)) # 全一数组
arr5 = np.arange(10) # 类似range的数组
arr6 = np.linspace(0, 1, 5) # 线性间隔数组
# 数组属性
print("数组形状:", arr2.shape) # (2, 2)
print("数组维度:", arr2.ndim) # 2
print("元素总数:", arr2.size) # 4
print("数据类型:", arr2.dtype) # int64
# 数组运算
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
print("数组相加:", a + b) # [5 7 9]
print("数组相乘:", a * b) # [4 10 18]
print("点积:", np.dot(a, b)) # 32
# 数组重塑
arr = np.arange(12).reshape(3, 4) # 改为3x4数组
# 数组拼接
a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6]])
c = np.concatenate([a, b], axis=0) # 垂直拼接
# 数组分割
arr = np.arange(16).reshape(4, 4)
upper, lower = np.vsplit(arr, [2]) # 垂直分割
# 排序
arr = np.array([3, 1, 4, 2])
print("排序结果:", np.sort(arr)) # [1 2 3 4]
# 随机数
random_arr = np.random.rand(3, 3) # 0-1均匀分布
normal_arr = np.random.randn(100) # 标准正态分布
# 线性代数
A = np.array([[1, 2], [3, 4]])
print("行列式:", np.linalg.det(A))
print("逆矩阵:\n", np.linalg.inv(A))
Pandas提供了DataFrame和Series数据结构,是数据分析的核心工具。
import pandas as pd
import numpy as np
# 创建Series
s = pd.Series([1, 3, 5, np.nan, 6, 8])
s2 = pd.Series({'a': 1, 'b': 2, 'c': 3}) # 从字典创建
# Series操作
print(s.values) # 值数组
print(s.index) # 索引
print(s[1:3]) # 切片
print(s.mean()) # 平均值
# 创建DataFrame
data = {'name': ['Alice', 'Bob', 'Charlie'],
'age': [25, 30, 35],
'city': ['NY', 'LA', 'SF']}
df = pd.DataFrame(data)
# 从NumPy数组创建
df2 = pd.DataFrame(np.random.randn(6, 4),
columns=list('ABCD'),
index=pd.date_range('20230101', periods=6))
# DataFrame基本操作
print(df.head(2)) # 前两行
print(df.tail(1)) # 最后一行
print(df.shape) # 形状 (3, 3)
print(df.columns) # 列名
print(df.index) # 索引
print(df.dtypes) # 每列数据类型
print(df.describe()) # 统计摘要
# 选择数据
print(df['name']) # 选择列
print(df[['name', 'age']]) # 选择多列
print(df.loc[0]) # 按标签选择行
print(df.iloc[1]) # 按位置选择行
print(df.iloc[1:3, 0:2]) # 行列切片
# 布尔索引
print(df[df['age'] > 28]) # 年龄大于28的行
print(df[(df['age'] > 25) & (df['city'] == 'NY')]) # 复合条件
# 添加/删除列
df['salary'] = [70000, 80000, 90000] # 添加列
df.drop('city', axis=1, inplace=True) # 删除列
# 处理缺失值
df_nan = pd.DataFrame({'A': [1, 2, np.nan], 'B': [5, np.nan, np.nan]})
print(df_nan.isna()) # 检测缺失值
print(df_nan.fillna(0)) # 填充缺失值
print(df_nan.dropna()) # 删除含缺失值的行
# 数据排序
print(df.sort_values('age', ascending=False)) # 按年龄降序
print(df.sort_index(ascending=False)) # 按索引降序
# 分组聚合
df = pd.DataFrame({'key': ['A', 'B', 'C', 'A', 'B', 'C'],
'data': range(6)})
print(df.groupby('key').sum()) # 按key分组求和
print(df.groupby('key').agg(['mean', 'std', 'count'])) # 多重聚合
# 数据合并
df1 = pd.DataFrame({'A': ['A0', 'A1'], 'B': ['B0', 'B1']})
df2 = pd.DataFrame({'A': ['A2', 'A3'], 'B': ['B2', 'B3']})
print(pd.concat([df1, df2])) # 垂直合并
df3 = pd.DataFrame({'key': ['K0', 'K1'], 'A': ['A0', 'A1']})
df4 = pd.DataFrame({'key': ['K0', 'K1'], 'B': ['B0', 'B1']})
print(pd.merge(df3, df4, on='key')) # 基于key合并
# 时间序列
dates = pd.date_range('20230101', periods=6)
ts = pd.Series(np.random.randn(6), index=dates)
print(ts.resample('M').mean()) # 按月重采样
print(ts.shift(2)) # 移动数据
# 数据输入/输出
df.to_csv('data.csv') # 保存到CSV
df_read = pd.read_csv('data.csv') # 读取CSV
df.to_excel('data.xlsx') # 保存到Excel
df_read = pd.read_excel('data.xlsx') # 读取Excel
# 透视表
df = pd.DataFrame({'A': ['foo', 'foo', 'foo', 'bar', 'bar', 'bar'],
'B': ['one', 'one', 'two', 'two', 'one', 'one'],
'C': [1, 2, 3, 4, 5, 6],
'D': [2.4, 3.1, 1.8, 2.9, 4.2, 3.6]})
print(pd.pivot_table(df, values='D', index=['A', 'B'], columns=['C']))
# 数据转换
df['age_bin'] = pd.cut(df['age'], bins=[20, 30, 40]) # 分箱
df['name_upper'] = df['name'].str.upper() # 字符串操作
# 类别数据
df['city'] = df['city'].astype('category') # 转换为类别类型
print(df['city'].cat.categories) # 查看类别
# 多级索引
arrays = [['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux'],
['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two']]
index = pd.MultiIndex.from_arrays(arrays, names=['first', 'second'])
df_multi = pd.DataFrame(np.random.randn(8, 4), index=index)
print(df_multi.loc[('bar', 'one')]) # 多级索引选择
# 性能优化
df_large = pd.DataFrame(np.random.randn(1000000, 4), columns=list('ABCD'))
%timeit df_large['A'] + df_large['B'] # 原生操作
%timeit df_large.values[:, 0] + df_large.values[:, 1] # NumPy操作更快
# 内存优化
print(df.memory_usage(deep=True)) # 查看内存使用
df['city'] = df['city'].astype('category') # 使用类别节省内存
xarray 是用于处理多维标记数据的库,特别适合气候、天气、海洋等科学数据。
import xarray as xr
import numpy as np
import pandas as pd
# 创建DataArray
data = np.random.rand(4, 3)
locs = ['IA', 'IL', 'IN']
times = pd.date_range('2000-01-01', periods=4)
foo = xr.DataArray(data, coords=[times, locs], dims=['time', 'space'])
print(foo)
# DataArray操作
print(foo.values) # NumPy数组
print(foo.dims) # 维度
print(foo.coords) # 坐标
print(foo.attrs) # 属性
foo.name = 'foo' # 设置名称
foo.attrs['units'] = 'meters' # 设置属性
# 索引和选择
print(foo[0, :]) # 第一时间的全部空间
print(foo.loc['2000-01-02':'2000-01-04']) # 按标签选择
print(foo.sel(time='2000-01-01', space='IL')) # 精确选择
print(foo.isel(time=0, space=1)) # 按整数索引选择
# 创建Dataset
ds = xr.Dataset({'temperature': (['time', 'space'], data),
'precipitation': (['time', 'space'], np.random.rand(4, 3))},
coords={'time': times,
'space': locs,
'reference_time': pd.Timestamp('2000-01-01')})
print(ds)
# Dataset操作
print(ds['temperature']) # 访问变量
print(ds[['temperature', 'precipitation']]) # 访问多个变量
ds['humidity'] = (['time', 'space'], np.random.rand(4, 3)) # 添加变量
print(ds.mean(dim='time')) # 沿时间维度平均
print(ds.groupby('time.month').mean()) # 按月份分组
# 计算
print(ds.temperature + ds.precipitation) # 变量间运算
print(np.sin(ds.temperature)) # 通用函数
print(xr.where(ds.temperature > 0.5, 1, 0)) # 条件运算
# 合并和连接
ds1 = xr.Dataset({'foo': ('x', [1, 2])}, coords={'x': [0, 1]})
ds2 = xr.Dataset({'foo': ('x', [3, 4])}, coords={'x': [2, 3]})
print(xr.concat([ds1, ds2], dim='x')) # 沿维度连接
# 输入输出
ds.to_netcdf('data.nc') # 保存为NetCDF
ds_read = xr.open_dataset('data.nc') # 读取NetCDF
# 可视化
ds.temperature.plot() # 简单绘图
# 重采样和时间操作
times = pd.date_range('2000-01-01', periods=365)
data = np.random.randn(365, 3)
ds = xr.Dataset({'temp': (['time', 'space'], data)},
coords={'time': times, 'space': ['A', 'B', 'C']})
monthly = ds.resample(time='M').mean() # 按月重采样
print(monthly)
# 滚动窗口
rolling = ds.rolling(time=7, center=True).mean() # 7天滚动平均
print(rolling)
# 分组操作
seasonal = ds.groupby('time.season').mean() # 按季节分组
print(seasonal)
# 自定义计算
def custom_func(x, a):
return x * a
result = xr.apply_ufunc(custom_func, ds.temperature, 2) # 应用自定义函数
print(result)
# 多文件处理
ds1 = xr.Dataset({'temp': (['x'], [1, 2])}, coords={'x': [0, 1]})
ds2 = xr.Dataset({'temp': (['x'], [3, 4])}, coords={'x': [2, 3]})
combined = xr.combine_by_coords([ds2, ds1]) # 按坐标合并
print(combined)
# 与Pandas交互
df = ds.temperature.to_dataframe() # 转换为DataFrame
print(df)
ds_from_df = df.to_xarray() # 从DataFrame转换回来
print(ds_from_df)
# 并行计算
import dask.array as da
data = da.random.random((10000, 10000), chunks=(1000, 1000))
ds = xr.Dataset({'big_data': (['x', 'y'], data)})
result = ds.big_data.mean(dim='x').compute() # 并行计算
print(result)
特性 | NumPy | Pandas | xarray |
---|---|---|---|
主要数据结构 | ndarray | Series/DataFrame | DataArray/Dataset |
维度标签 | 无 | 行/列标签 | 多维坐标标签 |
适用场景 | 通用数值计算 | 表格数据处理 | 多维标记数据 |
时间处理 | 有限 | 强大 | 非常强大 |
文件I/O | 基本 | 丰富 | 科学数据格式 |
# NumPy数组转为Pandas DataFrame
arr = np.random.randn(100, 3)
df = pd.DataFrame(arr, columns=['A', 'B', 'C'])
# Pandas DataFrame转为xarray Dataset
ds = df.to_xarray()
# 复杂数据处理流程
data = np.random.normal(0, 1, size=(100, 5))
df = pd.DataFrame(data, columns=['var1', 'var2', 'var3', 'var4', 'var5'])
df['date'] = pd.date_range('2020-01-01', periods=100)
ds = df.set_index(['date']).to_xarray()
本文详细介绍了Python数据处理三大核心库NumPy、Pandas和xarray的功能和用法。NumPy提供基础数组操作,Pandas擅长表格数据处理,xarray则专注于多维标记数据。掌握这三个库,可以应对绝大多数数据分析需求。