最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Pandas高效讀取CSV、Excel和SQL數據庫的數據

 更新時間:2026年05月22日 09:05:43   作者:小莊-Python辦公  
這篇文章主要為大家詳細介紹了使用Pandas高效讀取CSV、Excel和SQL數據庫的數據的相關知識,文中的示例代碼講解詳細,感興趣的小伙伴可以了解下

本節(jié)學習目標

完成本節(jié)學習后,你將能夠:

  1. 使用 pandas 從 CSV、TSV 等文本文件讀取數據
  2. 讀取 Excel 文件并處理多工作表
  3. 解決常見的編碼問題和數據格式異常
  4. 使用分塊讀取處理超過內存容量的大文件
  5. 連接 SQLite 和 MySQL 數據庫并執(zhí)行查詢
  6. 掌握數據讀取的性能優(yōu)化技巧

為什么學這個

在前面的課程中,我們用 NumPy 生成了各種模擬數據。但現實世界中,數據不會自動出現在你的代碼里——它們散落在各處:

  • 業(yè)務系統導出的 CSV 文件
  • 同事發(fā)來的 Excel 表格
  • 公司數據庫中的 SQL 表
  • 網頁上的 JSON 數據
  • 傳感器記錄的 日志文件

數據分析的第一步,就是把這些分散的數據"搬"到你的分析環(huán)境中。如果這一步做不好,后面的一切分析都是空中樓閣。

比喻:如果把數據分析比作做菜,那么數據載入就是"采購食材"。食材買錯了(格式不對)、買少了(數據不全)、或者買太多搬不動(內存溢出),這道菜就做不成了。

好消息是,pandas 提供了統一且強大的數據讀取接口。無論你面對什么格式的數據,幾乎都能用 pd.read_xxx() 一行代碼搞定。但實際情況往往沒那么簡單——編碼錯誤、格式異常、文件過大……這些問題才是真正考驗你功力的地方。

核心知識點講解

pandas 簡介——數據分析的"瑞士軍刀"

pandas 是基于 NumPy 構建的數據分析庫,它的名字來源于 Panel Data(面板數據)和 Python Data Science。

pandas 的兩個核心數據結構:

  • Series:一維帶標簽的數組(可以理解為"增強版的一維 NumPy 數組")
  • DataFrame:二維表格(可以理解為"增強版的 Excel 表格")
import pandas as pd
import numpy as np

# Series 示例
s = pd.Series([85, 92, 78, 96],
              index=['張三', '李四', '王五', '趙六'],
              name='數學成績')
print("Series:")
print(s)

# DataFrame 示例
df = pd.DataFrame({
    '姓名': ['張三', '李四', '王五', '趙六'],
    '數學': [85, 92, 78, 96],
    '英語': [88, 85, 92, 79],
    '語文': [76, 80, 85, 88]
})
print("\nDataFrame:")
print(df)

讀取 CSV 文件——最常見數據格式

基本讀取

CSV(Comma-Separated Values,逗號分隔值)是最常見的數據交換格式。

import pandas as pd

# 首先,我們創(chuàng)建一個 CSV 文件用于演示
data = {
    '訂單ID': range(1, 11),
    '商品': ['手機', '電腦', '平板', '耳機', '鍵盤',
            '鼠標', '顯示器', '音箱', '充電器', '數據線'],
    '價格': [2999, 5999, 1999, 199, 399,
            99, 1599, 499, 79, 29],
    '數量': [2, 1, 3, 5, 2,
            4, 1, 2, 10, 15],
    '日期': pd.date_range('2024-01-01', periods=10)
}
df = pd.DataFrame(data)
df.to_csv('sample_orders.csv', index=False, encoding='utf-8-sig')
print("示例 CSV 文件已創(chuàng)建")

# 讀取 CSV 文件
df_read = pd.read_csv('sample_orders.csv')
print("\n讀取的 DataFrame:")
print(df_read)
print(f"\n數據形狀: {df_read.shape}")
print(f"數據類型:\n{df_read.dtypes}")

read_csv 常用參數詳解

# 演示各種參數的用法
# 假設我們有一個稍微復雜一點的 CSV 文件
complex_csv = """ID,Name,Score,Grade,Comment
001,張三,85.5,A,
002,李四,92.0,B,優(yōu)秀
003,王五,,C,需要努力
004,趙六,78.5,A,進步很大
005,,88.0,B,繼續(xù)加油"""

# 先寫入文件
with open('complex_data.csv', 'w', encoding='utf-8') as f:
    f.write(complex_csv)

# 1. 基本讀取
print("1. 基本讀取:")
print(pd.read_csv('complex_data.csv'))

# 2. 指定列名
print("\n2. 指定列名:")
print(pd.read_csv('complex_data.csv',
                  names=['編號', '姓名', '分數', '等級', '評語'],
                  header=0))

# 3. 只讀取指定列
print("\n3. 只讀姓名列和分數列:")
print(pd.read_csv('complex_data.csv', usecols=['Name', 'Score']))

# 4. 處理缺失值
print("\n4. 默認缺失值處理:")
df = pd.read_csv('complex_data.csv')
print(df.isna().sum())  # 統計每列缺失值數量

# 5. 指定缺失值標記
print("\n5. 自定義缺失值標記:")
df = pd.read_csv('complex_data.csv', na_values=['', ' '])
print(df.isna().sum())

# 6. 解析日期列
df_with_date = pd.read_csv('sample_orders.csv', parse_dates=['日期'])
print("\n6. 日期列解析:")
print(df_with_date['日期'].dtype)  # 應該是 datetime64

# 7. 指定數據類型
print("\n7. 指定數據類型:")
df_typed = pd.read_csv('sample_orders.csv',
                       dtype={'訂單ID': str, '商品': 'category'})
print(df_typed.dtypes)

# 8. 跳過行
print("\n8. 跳過前2行:")
print(pd.read_csv('complex_data.csv', skiprows=2))

# 9. 讀取指定行數(用于預覽大文件)
print("\n9. 只讀前3行:")
print(pd.read_csv('sample_orders.csv', nrows=3))

# 10. 設置索引列
print("\n10. 設置索引列為訂單ID:")
df_idx = pd.read_csv('sample_orders.csv', index_col='訂單ID')
print(df_idx)

TSV 和其他分隔符

# TSV(制表符分隔)
tsv_data = "ID\tName\tScore\n1\t張三\t85\n2\t李四\t92"
with open('data.tsv', 'w', encoding='utf-8') as f:
    f.write(tsv_data)

print("TSV 文件讀取:")
df_tsv = pd.read_csv('data.tsv', sep='\t')  # 或直接用 pd.read_table()
print(df_tsv)

# 其他分隔符示例
pipe_data = "ID|Name|Score\n1|張三|85\n2|李四|92"
with open('data_pipe.txt', 'w', encoding='utf-8') as f:
    f.write(pipe_data)

print("\n管道符分隔讀取:")
df_pipe = pd.read_csv('data_pipe.txt', sep='|')
print(df_pipe)

讀取 Excel 文件——職場中最常見的格式

基本讀取

import pandas as pd

# 創(chuàng)建示例 Excel 文件
df1 = pd.DataFrame({
    '姓名': ['張三', '李四', '王五'],
    '部門': ['技術部', '市場部', '財務部'],
    '工資': [15000, 12000, 13000]
})
df2 = pd.DataFrame({
    '姓名': ['趙六', '錢七'],
    '部門': ['技術部', '人事部'],
    '工資': [16000, 11000]
})

# 寫入 Excel(需要 openpyxl 庫)
with pd.ExcelWriter('sample_data.xlsx', engine='openpyxl') as writer:
    df1.to_excel(writer, sheet_name='員工信息', index=False)
    df2.to_excel(writer, sheet_name='新員工', index=False)

print("Excel 文件已創(chuàng)建")

# 讀取 Excel
# 注意:需要安裝 openpyxl: pip install openpyxl
print("\n讀取第一個工作表:")
df_excel = pd.read_excel('sample_data.xlsx', sheet_name='員工信息')
print(df_excel)

# 查看所有工作表名
print("\n所有工作表:")
xls = pd.ExcelFile('sample_data.xlsx')
print(xls.sheet_names)

# 讀取所有工作表
print("\n讀取所有工作表:")
all_sheets = pd.read_excel('sample_data.xlsx', sheet_name=None)
for name, df in all_sheets.items():
    print(f"\n--- {name} ---")
    print(df)

Excel 讀取的實用技巧

# 1. 跳過表頭行
# 有些 Excel 文件前兩行是標題和說明
with pd.ExcelWriter('demo_skip.xlsx', engine='openpyxl') as writer:
    pd.DataFrame({'A': [1, 2, 3]}).to_excel(writer, sheet_name='data')

# 2. 指定列的數據類型
df = pd.read_excel('sample_data.xlsx', sheet_name='員工信息',
                   dtype={'工資': float})

# 3. 讀取指定范圍(需要引擎支持)
# df = pd.read_excel('file.xlsx', usecols='A:C', nrows=100)

# 4. 處理 Excel 中的空行
df = pd.read_excel('sample_data.xlsx', sheet_name='員工信息',
                   skip_blank_lines=True)

重要提示:讀取 Excel 文件需要安裝 openpyxl(用于 .xlsx)或 xlrd(用于舊版 .xls)庫。安裝方法:pip install openpyxl。

編碼問題處理——數據載入的"頭號殺手"

什么是編碼問題?

當你嘗試讀取一個 CSV 文件時,可能會看到這樣的錯誤:

UnicodeDecodeError: 'utf-8' codec can't decode byte 0xd0 in position 0

這是因為文件的編碼方式與讀取時指定的編碼不一致。

常見編碼方式

編碼說明適用場景
UTF-8國際通用編碼,支持所有語言現代系統默認
GBK / GB2312中文編碼Windows 中文系統
GB18030擴展中文編碼生僻字支持
Latin-1西歐編碼歐洲語言
ASCII基礎編碼純英文

如何判斷文件編碼

# 方法1:使用 chardet 庫自動檢測
# pip install chardet
import chardet

with open('sample_orders.csv', 'rb') as f:
    raw_data = f.read(10000)  # 讀取前10000字節(jié)
    result = chardet.detect(raw_data)
    print(f"檢測到的編碼: {result['encoding']}")
    print(f"置信度: {result['confidence']:.2%}")

# 方法2:用 pandas 的 errors 參數處理
# ignore:忽略無法解碼的字符
# replace:用 ? 替換無法解碼的字符
# surrogateescape:特殊處理(Python 3.1+)

# 方法3:嘗試多種編碼
def read_with_encoding(filepath, encodings=['utf-8', 'gbk', 'gb18030', 'latin-1']):
    for enc in encodings:
        try:
            df = pd.read_csv(filepath, encoding=enc)
            print(f"成功使用 {enc} 編碼讀取")
            return df
        except UnicodeDecodeError:
            continue
    raise ValueError("無法用任何編碼讀取文件")

df = read_with_encoding('sample_orders.csv')

實際解決方案

# Windows 系統導出的 CSV 通常使用 GBK 編碼
# 解決方案1:指定編碼
df = pd.read_csv('data.csv', encoding='gbk')

# 解決方案2:使用 utf-8-sig(處理帶 BOM 的 UTF-8)
# BOM (Byte Order Mark) 是 UTF-8 文件開頭的特殊標記
df = pd.read_csv('data.csv', encoding='utf-8-sig')

# 解決方案3:用 Notepad++ 或 VS Code 轉換文件編碼
# 打開文件 -> 轉換為 UTF-8 -> 保存

最佳實踐:在團隊協作中,統一規(guī)定所有數據文件使用 UTF-8 編碼,可以省去大量麻煩。

大數據分塊讀取——處理超內存文件

什么時候需要分塊讀取?

當你的 CSV 文件有 10GB,而你的電腦只有 8GB 內存時,直接 pd.read_csv() 會失敗(MemoryError)。

分塊讀取的策略是:每次只讀取一小部分,處理完后釋放內存,再讀取下一部分。

import pandas as pd
import numpy as np

# 先創(chuàng)建一個大文件用于演示(模擬 100 萬行數據)
np.random.seed(42)
n_rows = 1_000_000
large_df = pd.DataFrame({
    'id': range(n_rows),
    'value1': np.random.normal(100, 20, n_rows),
    'value2': np.random.normal(50, 10, n_rows),
    'category': np.random.choice(['A', 'B', 'C', 'D'], n_rows),
    'date': pd.date_range('2020-01-01', periods=n_rows, freq='min')
})
large_df.to_csv('large_data.csv', index=False)
print(f"已創(chuàng)建包含 {n_rows} 行數據的文件")

方式1:使用 chunksize 參數

# 每次讀取 10 萬行
chunk_size = 100_000
total_rows = 0
total_value1 = 0
total_value2 = 0

for chunk in pd.read_csv('large_data.csv', chunksize=chunk_size):
    total_rows += len(chunk)
    total_value1 += chunk['value1'].sum()
    total_value2 += chunk['value2'].sum()
    print(f"已處理 {total_rows} 行...")

print(f"\n總行數: {total_rows}")
print(f"value1 總和: {total_value1:,.2f}")
print(f"value2 總和: {total_value2:,.2f}")

方式2:分塊聚合(計算統計量)

# 計算大文件的整體統計信息
chunk_size = 100_000
stats = {
    'count': 0,
    'sum_v1': 0, 'sum_v2': 0,
    'sum_sq_v1': 0, 'sum_sq_v2': 0,
    'min_v1': float('inf'), 'max_v1': float('-inf'),
    'min_v2': float('inf'), 'max_v2': float('-inf')
}

for chunk in pd.read_csv('large_data.csv',
                         usecols=['value1', 'value2'],  # 只讀需要的列
                         chunksize=chunk_size):

    stats['count'] += len(chunk)
    stats['sum_v1'] += chunk['value1'].sum()
    stats['sum_v2'] += chunk['value2'].sum()
    stats['sum_sq_v1'] += (chunk['value1'] ** 2).sum()
    stats['sum_sq_v2'] += (chunk['value2'] ** 2).sum()
    stats['min_v1'] = min(stats['min_v1'], chunk['value1'].min())
    stats['max_v1'] = max(stats['max_v1'], chunk['value1'].max())
    stats['min_v2'] = min(stats['min_v2'], chunk['value2'].min())
    stats['max_v2'] = max(stats['max_v2'], chunk['value2'].max())

# 計算均值和標準差
mean_v1 = stats['sum_v1'] / stats['count']
mean_v2 = stats['sum_v2'] / stats['count']
std_v1 = (stats['sum_sq_v1'] / stats['count'] - mean_v1 ** 2) ** 0.5
std_v2 = (stats['sum_sq_v2'] / stats['count'] - mean_v2 ** 2) ** 0.5

print("大文件統計信息:")
print(f"  value1: 均值={mean_v1:.2f}, 標準差={std_v1:.2f}, "
      f"范圍=[{stats['min_v1']:.2f}, {stats['max_v1']:.2f}]")
print(f"  value2: 均值={mean_v2:.2f}, 標準差={std_v2:.2f}, "
      f"范圍=[{stats['min_v2']:.2f}, {stats['max_v2']:.2f}]")

方式3:迭代器模式(更靈活的控制)

# 使用 iterator 參數,手動控制迭代
reader = pd.read_csv('large_data.csv', chunksize=50000, iterator=True)

# 可以跳過某些 chunk
for i, chunk in enumerate(reader):
    if i == 0:
        print(f"第 {i} 塊,形狀: {chunk.shape}")
        # 保存第一塊作為參考
        sample = chunk.head()
    # 只處理 category 為 A 的數據
    filtered = chunk[chunk['category'] == 'A']
    if len(filtered) > 0:
        pass  # 處理過濾后的數據

分塊讀取的注意事項

  1. 只讀需要的列:使用 usecols 參數,減少內存占用
  2. 指定數據類型:使用 dtype 參數,避免 pandas 自動推斷導致的內存浪費
  3. 跳過不需要的行:使用 skiprows 參數
# 優(yōu)化版分塊讀取
optimized_chunks = pd.read_csv(
    'large_data.csv',
    chunksize=100_000,
    usecols=['id', 'value1', 'category'],  # 只讀3列
    dtype={'id': 'int32', 'value1': 'float32', 'category': 'category'}  # 節(jié)省內存
)

for chunk in optimized_chunks:
    # 處理每個塊
    pass

連接數據庫——從 SQL 讀取數據

SQLite——內置數據庫(無需安裝服務器)

import pandas as pd
import sqlite3

# 創(chuàng)建 SQLite 數據庫
conn = sqlite3.connect('sample_database.db')
cursor = conn.cursor()

# 創(chuàng)建表
cursor.execute('''
    CREATE TABLE IF NOT EXISTS employees (
        id INTEGER PRIMARY KEY,
        name TEXT,
        department TEXT,
        salary REAL,
        hire_date TEXT
    )
''')

# 插入數據
employees = [
    (1, '張三', '技術部', 15000, '2020-03-15'),
    (2, '李四', '市場部', 12000, '2021-06-01'),
    (3, '王五', '財務部', 13000, '2019-11-20'),
    (4, '趙六', '技術部', 18000, '2018-08-10'),
    (5, '錢七', '人事部', 11000, '2022-01-05'),
]
cursor.executemany('INSERT OR REPLACE INTO employees VALUES (?, ?, ?, ?, ?)',
                   employees)
conn.commit()

# 方式1:直接讀取整個表
print("1. 讀取整個表:")
df_sqlite = pd.read_sql('SELECT * FROM employees', conn)
print(df_sqlite)

# 方式2:帶條件的查詢
print("\n2. 查詢技術部員工:")
df_tech = pd.read_sql(
    "SELECT name, salary FROM employees WHERE department = '技術部'",
    conn
)
print(df_tech)

# 方式3:使用 read_sql_query(等價于 read_sql)
print("\n3. 平均工資查詢:")
df_avg = pd.read_sql_query(
    "SELECT department, AVG(salary) as avg_salary, COUNT(*) as count "
    "FROM employees GROUP BY department",
    conn
)
print(df_avg)

# 方式4:使用 read_sql_table(讀取整張表,SQLite 不支持)
# df = pd.read_sql_table('employees', conn)  # 需要 SQLAlchemy

# 方式5:DataFrame 直接寫入數據庫
df_new = pd.DataFrame({
    'id': [6, 7],
    'name': ['孫八', '周九'],
    'department': ['技術部', '市場部'],
    'salary': [16000, 13500],
    'hire_date': ['2023-05-10', '2023-08-20']
})
df_new.to_sql('employees', conn, if_exists='append', index=False)
print("\n4. 新增數據后:")
print(pd.read_sql('SELECT * FROM employees', conn))

# 關閉連接
conn.close()

MySQL 連接(需要安裝 pymysql)

# 注意:以下代碼需要 MySQL 服務器運行
# 安裝: pip install pymysql

# 連接 MySQL
# conn_mysql = create_engine('mysql+pymysql://username:password@localhost:3306/database_name')

# 讀取數據
# df = pd.read_sql('SELECT * FROM table_name', conn_mysql)

# 示例代碼(注釋狀態(tài),實際運行需要 MySQL)
"""
from sqlalchemy import create_engine

engine = create_engine('mysql+pymysql://root:password@localhost:3306/mydb')

# 讀取數據
df = pd.read_sql('SELECT * FROM users', engine)

# 寫入數據
df.to_sql('users_backup', engine, if_exists='replace', index=False)

# 復雜查詢
df = pd.read_sql('''
    SELECT d.department_name,
           AVG(e.salary) as avg_salary,
           COUNT(e.id) as emp_count
    FROM employees e
    JOIN departments d ON e.dept_id = d.id
    GROUP BY d.department_name
    ORDER BY avg_salary DESC
''', engine)
"""

提示:如果你使用 PostgreSQL,安裝 psycopg2 包,連接字符串改為 postgresql+psycopg2://...。

其他數據格式讀取

JSON

import json

# 創(chuàng)建示例 JSON
json_data = [
    {"name": "張三", "age": 25, "city": "北京"},
    {"name": "李四", "age": 30, "city": "上海"},
    {"name": "王五", "age": 28, "city": "廣州"}
]
with open('sample.json', 'w', encoding='utf-8') as f:
    json.dump(json_data, f, ensure_ascii=False)

# 讀取 JSON
df_json = pd.read_json('sample.json')
print("JSON 讀取:")
print(df_json)

# 復雜 JSON(嵌套結構)
complex_json = '''
{
    "employees": {
        "張三": {"age": 25, "dept": "技術部"},
        "李四": {"age": 30, "dept": "市場部"}
    }
}
'''
with open('complex.json', 'w', encoding='utf-8') as f:
    f.write(complex_json)

# orient 參數處理不同 JSON 格式
df_complex = pd.read_json('complex.json', orient='index')
print("\n復雜 JSON 讀取:")
print(df_complex)

HTML 表格

# 讀取網頁中的表格
# url = 'https://en.wikipedia.org/wiki/List_of_countries_by_GDP_(nominal)'
# tables = pd.read_html(url)
# print(f"頁面中找到 {len(tables)} 個表格")
# print(tables[0].head())  # 第一個表格

# 這里用本地 HTML 演示
html_table = """
<table>
    <tr><th>姓名</th><th>成績</th></tr>
    <tr><td>張三</td><td>85</td></tr>
    <tr><td>李四</td><td>92</td></tr>
    <tr><td>王五</td><td>78</td></tr>
</table>
"""
with open('sample.html', 'w', encoding='utf-8') as f:
    f.write(html_table)

df_html = pd.read_html('sample.html')[0]
print("HTML 表格讀取:")
print(df_html)

代碼示例:綜合實戰(zhàn)

實戰(zhàn)1:多源數據整合分析

import pandas as pd
import numpy as np
import sqlite3

# 場景:整合來自不同數據源的信息

# 數據源1:CSV 文件(員工基本信息)
emp_csv = pd.DataFrame({
    'emp_id': [1, 2, 3, 4, 5],
    'name': ['張三', '李四', '王五', '趙六', '錢七'],
    'gender': ['男', '女', '男', '男', '女'],
    'birth_year': [1990, 1988, 1992, 1985, 1993]
})
emp_csv.to_csv('employees_basic.csv', index=False, encoding='utf-8-sig')

# 數據源2:Excel 文件(績效數據)
perf_excel = pd.DataFrame({
    'emp_id': [1, 2, 3, 4, 5],
    'q1_score': [85, 92, 78, 96, 88],
    'q2_score': [88, 90, 82, 94, 85],
    'q3_score': [90, 88, 85, 92, 90]
})
with pd.ExcelWriter('employees_perf.xlsx', engine='openpyxl') as writer:
    perf_excel.to_excel(writer, sheet_name='績效', index=False)

# 數據源3:SQLite 數據庫(薪資數據)
conn = sqlite3.connect('salary.db')
pd.DataFrame({
    'emp_id': [1, 2, 3, 4, 5],
    'base_salary': [15000, 12000, 13000, 18000, 11000],
    'bonus': [3000, 5000, 2000, 8000, 2500]
}).to_sql('salary', conn, if_exists='replace', index=False)

# 整合分析
print("=" * 50)
print("多源數據整合分析")
print("=" * 50)

# 讀取各數據源
basic = pd.read_csv('employees_basic.csv')
perf = pd.read_excel('employees_perf.xlsx', sheet_name='績效')
salary = pd.read_sql('SELECT * FROM salary', conn)

# 合并數據
merged = basic.merge(perf, on='emp_id').merge(salary, on='emp_id')
merged['avg_score'] = merged[['q1_score', 'q2_score', 'q3_score']].mean(axis=1)
merged['total_income'] = merged['base_salary'] + merged['bonus']

print("\n整合后的完整數據:")
print(merged.to_string())

print("\n各季度平均績效:")
print(f"  Q1: {perf['q1_score'].mean():.1f}")
print(f"  Q2: {perf['q2_score'].mean():.1f}")
print(f"  Q3: {perf['q3_score'].mean():.1f}")

print("\n平均薪資:")
print(f"  基本薪資均值: ¥{salary['base_salary'].mean():,.0f}")
print(f"  獎金均值: ¥{salary['bonus'].mean():,.0f}")
print(f"  總收入均值: ¥{merged['total_income'].mean():,.0f}")

conn.close()

實戰(zhàn)2:大文件處理流水線

import pandas as pd
import numpy as np

# 創(chuàng)建模擬日志文件(50 萬行)
np.random.seed(42)
n = 500_000
log_data = pd.DataFrame({
    'timestamp': pd.date_range('2024-01-01', periods=n, freq='s'),
    'user_id': np.random.randint(1, 10000, n),
    'action': np.random.choice(['click', 'view', 'purchase', 'logout'], n,
                               p=[0.5, 0.3, 0.15, 0.05]),
    'page': np.random.choice(['home', 'product', 'cart', 'checkout', 'help'], n),
    'duration_ms': np.random.exponential(2000, n).astype(int)
})
log_data.to_csv('web_logs.csv', index=False)
print(f"已創(chuàng)建 {n} 行日志數據")

# 分塊讀取并聚合
print("\n分塊處理日志數據:")

stats = {}
chunk_size = 50_000

for chunk in pd.read_csv('web_logs.csv',
                         usecols=['action', 'user_id', 'duration_ms'],
                         chunksize=chunk_size):

    # 按 action 分組統計
    action_counts = chunk['action'].value_counts()
    for action, count in action_counts.items():
        stats[action] = stats.get(action, 0) + count

    # 統計總用戶數
    stats['unique_users'] = len(chunk['user_id'].unique())

    print(f"處理 {chunk_size} 行...")

print("\n統計結果:")
for action, count in stats.items():
    print(f"  {action}: {count:,}" if action != 'unique_users'
          else f"  獨立用戶數: {count:,}")

實戰(zhàn)練習

練習1:CSV 讀取與清洗

題目:創(chuàng)建一個包含臟數據的 CSV 文件,然后讀取并清洗:

  • 包含空值
  • 包含重復行
  • 包含錯誤類型(如價格列出現了文本)

參考答案

import pandas as pd
import numpy as np

# 創(chuàng)建臟數據
dirty_csv = """id,name,price,quantity
1,手機,2999,2
2,電腦,5999,1
3,,1999,3
4,耳機,abc,5
5,鍵盤,399,2
1,手機,2999,2
6,鼠標,99,
"""
with open('dirty_data.csv', 'w', encoding='utf-8') as f:
    f.write(dirty_csv)

# 讀取并清洗
df = pd.read_csv('dirty_data.csv')

print("原始數據:")
print(df)

# 1. 刪除完全重復的行
df = df.drop_duplicates()

# 2. 刪除 name 為空的行
df = df.dropna(subset=['name'])

# 3. 處理 price 列的文本(轉換為數字,無效的變 NaN)
df['price'] = pd.to_numeric(df['price'], errors='coerce')

# 4. 填充 quantity 的缺失值為 1
df['quantity'] = df['quantity'].fillna(1).astype(int)

# 5. 刪除 price 仍然為 NaN 的行
df = df.dropna(subset=['price'])

print("\n清洗后數據:")
print(df)

練習2:分塊統計

題目:用分塊讀取的方式,計算大文件中每個 category 的平均值。

參考答案

import pandas as pd
import numpy as np
from collections import defaultdict

# 先創(chuàng)建大文件
np.random.seed(42)
n = 200_000
big = pd.DataFrame({
    'category': np.random.choice(['A', 'B', 'C', 'D', 'E'], n),
    'value': np.random.normal(50, 15, n)
})
big.to_csv('big_categories.csv', index=False)

# 分塊統計
cat_stats = defaultdict(lambda: {'sum': 0, 'count': 0})

for chunk in pd.read_csv('big_categories.csv', chunksize=50000):
    for cat, group in chunk.groupby('category'):
        cat_stats[cat]['sum'] += group['value'].sum()
        cat_stats[cat]['count'] += len(group)

print("分類統計:")
for cat, stats in sorted(cat_stats.items()):
    mean = stats['sum'] / stats['count']
    print(f"  {cat}: 均值={mean:.2f}, 數量={stats['count']}")

練習3:數據庫查詢整合

題目:創(chuàng)建一個 SQLite 數據庫,包含訂單表和客戶表,然后用 JOIN 查詢每個客戶的總消費金額。

參考答案

import pandas as pd
import sqlite3

conn = sqlite3.connect('shop.db')

# 創(chuàng)建客戶表
customers = pd.DataFrame({
    'customer_id': [1, 2, 3, 4, 5],
    'name': ['張三', '李四', '王五', '趙六', '錢七'],
    'city': ['北京', '上海', '廣州', '深圳', '杭州']
})
customers.to_sql('customers', conn, if_exists='replace', index=False)

# 創(chuàng)建訂單表
orders = pd.DataFrame({
    'order_id': range(1, 11),
    'customer_id': [1, 2, 1, 3, 2, 4, 1, 5, 3, 2],
    'amount': [500, 800, 300, 1200, 600, 400, 700, 900, 350, 550]
})
orders.to_sql('orders', conn, if_exists='replace', index=False)

# JOIN 查詢
result = pd.read_sql('''
    SELECT c.name, c.city,
           COUNT(o.order_id) as order_count,
           SUM(o.amount) as total_spent,
           AVG(o.amount) as avg_order
    FROM customers c
    LEFT JOIN orders o ON c.customer_id = o.customer_id
    GROUP BY c.customer_id
    ORDER BY total_spent DESC
''', conn)

print("客戶消費分析:")
print(result.to_string())

conn.close()

本節(jié)總結

本節(jié)我們全面學習了從各種數據源讀取數據的方法。關鍵要點:

CSV 讀取是基本功:掌握 pd.read_csv() 的各種參數——sep、encoding、usecolsdtype、parse_dates、nrows、chunksize 等。

編碼問題是日常痛點:Windows 中文系統導出的文件通常用 GBK 編碼。遇到問題時,嘗試 encoding='gbk'encoding='utf-8-sig'。使用 chardet 庫可以自動檢測編碼。

分塊讀取解決大文件:當文件超過內存容量時,使用 chunksize 參數分塊處理。配合 usecolsdtype 參數可以進一步優(yōu)化內存。

數據庫讀取很靈活pd.read_sql() 可以執(zhí)行任意 SQL 查詢,直接在數據庫層面完成過濾和聚合,只讀取需要的結果,效率最高。

性能優(yōu)化三板斧

  • 只讀需要的列(usecols
  • 指定數據類型(dtype),特別是 category 類型可以大幅節(jié)省內存
  • 在數據庫層面完成過濾,減少數據傳輸量

多種格式統一接口:無論是 CSV、Excel、JSON 還是數據庫,pandas 都提供了 read_xxx() 的統一接口,降低了學習成本。

實用建議:在實際工作中,先花 5 分鐘檢查數據文件的編碼、格式和大小,再決定用哪種方式讀取。這一步可以避免后面 90% 的問題。

下一節(jié)預告

恭喜!你已經完成了第一階段的全部內容?;仡櫼幌履阏莆盏募寄埽?/p>

  • 環(huán)境配置與 Jupyter Notebook 使用
  • NumPy 數組的創(chuàng)建、運算和廣播
  • 高級索引、維度變換和矩陣運算
  • 向量化思維,讓代碼效率提升百倍
  • 從各種數據源高效讀取數據

接下來,我們將進入第二階段,開始學習 pandas 的核心功能——數據處理與分析。你將掌握:

  • DataFrame 的基本操作和行列選擇
  • 數據清洗與預處理
  • 數據分組與聚合(groupby)
  • 數據合并與連接(merge/concat)

pandas 才是數據分析的主力工具,讓我們繼續(xù)前進!

以上就是Pandas高效讀取CSV、Excel和SQL數據庫的數據的詳細內容,更多關于Pandas數據讀取的資料請關注腳本之家其它相關文章!

相關文章

  • Python time庫的時間時鐘處理

    Python time庫的時間時鐘處理

    這篇文章主要介紹了Python time庫的時間時鐘處理,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-05-05
  • python編寫網頁爬蟲腳本并實現APScheduler調度

    python編寫網頁爬蟲腳本并實現APScheduler調度

    爬蟲爬的頁面是京東的電子書網站頁面,每天會更新一些免費的電子書,爬蟲會把每天更新的免費的書名以第一時間通過郵件發(fā)給我,通知我去下載
    2014-07-07
  • Pytorch建模過程中的DataLoader與Dataset示例詳解

    Pytorch建模過程中的DataLoader與Dataset示例詳解

    這篇文章主要介紹了Pytorch建模過程中的DataLoader與Dataset,同時PyTorch針對不同的專業(yè)領域,也提供有不同的模塊,例如?TorchText,?TorchVision,?TorchAudio,這些模塊中也都包含一些真實數據集示例,本文給大家介紹的非常詳細,需要的朋友參考下吧
    2023-01-01
  • Python獲取接口數據的實現示例

    Python獲取接口數據的實現示例

    本文主要介紹了Python獲取接口數據的實現示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-07-07
  • python實現帶聲音的摩斯碼翻譯實現方法

    python實現帶聲音的摩斯碼翻譯實現方法

    這篇文章主要介紹了python實現帶聲音的摩斯碼翻譯實現方法,涉及pygame模塊操作及摩斯碼實現技巧,需要的朋友可以參考下
    2015-05-05
  • 對python中Json與object轉化的方法詳解

    對python中Json與object轉化的方法詳解

    今天小編就為大家分享一篇對python中Json與object轉化的方法詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-12-12
  • wxPython窗體拆分布局基礎組件

    wxPython窗體拆分布局基礎組件

    這篇文章主要為大家詳細介紹了wxPython窗體拆分布局基礎組件,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-11-11
  • 利用python繪制中國地圖(含省界、河流等)

    利用python繪制中國地圖(含省界、河流等)

    這篇文章主要介紹了利用python繪制中國地圖,幫助大家更好的理解和使用python繪制圖形,感興趣的朋友可以了解下
    2020-09-09
  • pycharm通過anaconda安裝pyqt5的教程

    pycharm通過anaconda安裝pyqt5的教程

    PyCharm是一種Python IDE,帶有一整套可以幫助用戶在使用Python語言開發(fā)時提高其效率的工具,這篇文章主要介紹了pycharm通過anaconda來安裝pyqt5的教程,需要的朋友可以參考下
    2020-03-03
  • Python virtualenv虛擬環(huán)境實現過程解析

    Python virtualenv虛擬環(huán)境實現過程解析

    這篇文章主要介紹了Python virtualenv虛擬環(huán)境實現過程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-04-04

最新評論

壶关县| 蕉岭县| 游戏| 昆山市| 咸丰县| 蒲城县| 丹东市| 集贤县| 乌兰浩特市| 永善县| 日土县| 阿瓦提县| 林甸县| 安图县| 辉南县| 鄂托克旗| 磴口县| 呈贡县| 柳江县| 象山县| 手机| 永昌县| 恩平市| 颍上县| 定西市| 郧西县| 昌吉市| 成都市| 卢湾区| 英吉沙县| 普安县| 宁河县| 马尔康县| 太仓市| 安福县| 科尔| 东方市| 华宁县| 三江| 锡林浩特市| 仲巴县|