Home > Techniques > Python > 【笔记整理|2024年上半年】Python数据分析与可视化技术指南

【笔记整理|2024年上半年】Python数据分析与可视化技术指南
python data-analysis numpy scipy matplotlib seaborn pandas visualization performance research

【笔记整理|2024年上半年】Python数据分析与可视化技术指南

本文汇总了在科研数据分析中使用Python的实用技巧,涵盖数据处理、可视化、性能分析等核心技术。

NumPy和SciPy数据处理

数组操作和统计分析

寻找数组中的局部极值

使用scipy.signal.argrelextrema函数寻找一维数组中的相对极值(最大值和最小值):

import numpy as np
from scipy.signal import argrelextrema
from scipy.stats import gaussian_kde

# 示例:寻找密度函数的局部最小值
data = np.array([...])  # 你的数据
density = gaussian_kde(data)
x = np.linspace(data.min(), data.max(), 1000)
y = density(x)

# 寻找局部最小值
minima_indices = argrelextrema(y, np.less)
minima = x[minima_indices]

注意argrelextrema函数寻找y是局部最小值的索引(即小于其邻居的点)。

数组处理常见问题

# 处理数组转换失败的问题
# "cannot process into arrays" 错误通常是由于数据类型不一致
try:
    arr1 = np.array(str1.split())
    result = np.array([float(x) for x in arr1])
except ValueError as e:
    print(f"Array conversion failed: {e}")

数据可视化

Matplotlib配置和使用

基础导入和配置

import matplotlib.pyplot as plt
import matplotlib

# 获取matplotlib缓存目录
cache_dir = matplotlib.get_cachedir()
print(f"Matplotlib cache directory: {cache_dir}")

字体和缓存问题解决

import os
import matplotlib

# 清理matplotlib字体缓存
font_directory = os.path.join(matplotlib.get_data_path(), 'fonts', 'ttf')

# 如果遇到字体问题,删除缓存重新生成
# rm -r /home/username/.cache/matplotlib

Seaborn可视化技巧

Violin Plot使用和问题解决

import seaborn as sns
import matplotlib.pyplot as plt

# 创建violin plot
sns.violinplot(data=data)

# 常见问题:分布显示为负值(但数据全为正)
# 解决方案:使用内核密度估计的截断参数
sns.violinplot(data=data, cut=0)  # cut=0避免扩展到数据范围之外

问题说明:使用sns.violinplot时发现某些分布低于0,但数据全为正值。这是因为核密度估计默认会在数据范围外进行插值。

Violin Plot进阶用法

Violin Plot数据分析指南:https://www.geeksforgeeks.org/violin-plot-for-data-analysis/

分组柱状图制作

多种方法实现分组柱状图

当数据格式为矩阵时,创建分组柱状图的5种方法:

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

# 方法1:使用matplotlib
def method1_matplotlib(data_matrix):
    x = np.arange(len(data_matrix))
    width = 0.35
    fig, ax = plt.subplots()
    for i in range(data_matrix.shape[1]):
        ax.bar(x + i*width, data_matrix[:, i], width, label=f'Group {i+1}')
    ax.legend()

# 方法2:使用pandas
def method2_pandas(data_matrix):
    df = pd.DataFrame(data_matrix)
    df.plot(kind='bar', ax=plt.gca())

# 方法3:使用seaborn
def method3_seaborn(data_matrix):
    df = pd.DataFrame(data_matrix)
    df_melted = df.melt()
    sns.barplot(data=df_melted, x='variable', y='value')

# 其他方法可参考plotnine等工具

Pandas数据操作

基础数据处理

import pandas as pd

# 基本数据导入和处理
df = pd.read_csv('data.csv')

数据结构操作

字典排序

# 按键对字典进行排序
mydict = {'c': 3, 'a': 1, 'b': 2}
sorted_mydict = dict(sorted(mydict.items(), key=lambda item: item[0]))

Python字典排序指南:https://www.golinuxcloud.com/python-sort-dictionary-by-key/

性能分析与优化

代码性能分析

cProfile性能分析

在Python中,可以使用cProfile模块来分析每个函数的执行时间:

import cProfile
cProfile.run('your_function()')

不同运行环境性能对比

实际测试发现:

  • PyCharm profile:71秒
  • 简单debug模式:56秒
  • 命令行直接运行:31秒

性能分析显示主要耗时操作:

  • fit操作:约8秒
  • concat操作:6秒
  • process_dict:11.6秒

算法复杂度理解

Python排序算法

Python内置的sorted()函数使用双轴快排算法(timsort),时间复杂度:

  • 最坏情况:O(n * log n)
  • 平均情况:O(n * log n)

W3Schools Python sorted()函数:https://www.w3schools.com/python/ref_func_sorted.asp

哈希表查找效率

集合和字典在Python中都通过哈希表实现,元素查找时间复杂度通常为O(1),这使得元素位置可以快速定位。

高阶函数与函数式编程

函数套用(高阶函数)

在Python中,函数可以套用函数,这是一种常见的编程模式,也被称为高阶函数。这意味着一个函数可以接受另一个函数作为参数,或者返回一个函数作为结果。

动态属性设置

# 使用setattr动态设置对象属性
setattr(obj, 'attribute_name', value)

# __getattr__方法在访问不存在的属性时被调用
def __getattr__(self, name):
    # 处理不存在的属性访问
    pass

图论和网络分析

节点连接分析

处理图中节点组之间的连接问题:

# 问题:找到连接两个节点组的节点对
# 可能每个节点组对有一个节点对连接
# 解决思路:构建二分图可能有助于快速找到这些连接

def find_connecting_pairs(graph, group1, group2):
    """
    找到连接两个节点组的节点对
    考虑使用二分图表示来优化搜索
    """
    connecting_pairs = []
    for node1 in group1:
        for node2 in group2:
            if graph.has_edge(node1, node2):
                connecting_pairs.append((node1, node2))
    return connecting_pairs

列表元素计数

# 统计列表中元素出现次数的多种方法
from collections import Counter

# 方法1:使用Counter
my_list = [1, 2, 2, 3, 3, 3]
counts = Counter(my_list)

Python列表元素计数方法:https://datagy.io/python-count-occurrences-in-list/

组合与迭代

列表组合生成

import itertools
# 获取两个列表的所有唯一组合
combinations = list(itertools.product(list1, list2))

Python组合生成教程:https://www.geeksforgeeks.org/python-program-to-get-all-unique-combinations-of-two-lists/

迭代中修改集合

# 错误示例:迭代过程中修改集合大小
RuntimeError: Set changed size during iteration

避免在迭代过程中修改正在迭代的集合。

科研数据处理最佳实践

数据验证

def validate_data(data):
    """验证科研数据的基本检查"""
    # 检查数据范围合理性
    if np.any(data < 0) and data_should_be_positive:
        print("Warning: Found negative values in positive-only data")

    # 检查缺失值
    if np.any(np.isnan(data)):
        print("Warning: Found NaN values")

    # 检查异常值
    q1, q3 = np.percentile(data, [25, 75])
    iqr = q3 - q1
    outliers = (data < q1 - 1.5*iqr) | (data > q3 + 1.5*iqr)
    if np.any(outliers):
        print(f"Warning: Found {np.sum(outliers)} potential outliers")

可重现性保证

# 设置随机种子确保结果可重现
np.random.seed(42)

# 保存分析环境信息
def save_environment_info():
    import sys
    import numpy
    import matplotlib
    import pandas

    env_info = {
        'python_version': sys.version,
        'numpy_version': numpy.__version__,
        'matplotlib_version': matplotlib.__version__,
        'pandas_version': pandas.__version__
    }
    return env_info

大数据处理

# 处理大型数组时的内存优化
def process_large_array(data, chunk_size=1000):
    """分块处理大型数组"""
    results = []
    for i in range(0, len(data), chunk_size):
        chunk = data[i:i+chunk_size]
        processed_chunk = process_chunk(chunk)
        results.append(processed_chunk)
    return np.concatenate(results)

向量化计算

# 优先使用NumPy向量化操作而非Python循环
# 低效方式
def slow_calculation(data):
    results = []
    for x in data:
        results.append(x**2 + 2*x + 1)
    return results

# 高效方式
def fast_calculation(data):
    return data**2 + 2*data + 1

第三方库和工具

Plotnine使用

# plotnine相关问题和解决方案

Plotnine GitHub问题:https://github.com/has2k1/plotnine/issues/79

plotnine是Python中ggplot2的实现,适合熟悉R语法的用户。

调试和故障排除

常见错误模式

  1. 数组转换失败:通常由数据类型不一致造成
  2. 可视化异常值:密度估计超出数据范围
  3. 内存不足:大数据集处理时的常见问题
  4. 迭代修改错误:在迭代过程中修改集合

调试建议

  • 使用print()语句检查中间结果
  • 利用Jupyter notebook的交互式特性
  • 保存关键步骤的中间数据
  • 记录完整的软件环境信息

本文基于2023年9月至2024年上半年的技术实践整理,涵盖Python数据分析和可视化的核心技术要点