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

Pandas高效讀取CSV、Excel和SQL數(shù)據(jù)庫(kù)的數(shù)據(jù)

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

本節(jié)學(xué)習(xí)目標(biāo)

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

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

為什么學(xué)這個(gè)

在前面的課程中,我們用 NumPy 生成了各種模擬數(shù)據(jù)。但現(xiàn)實(shí)世界中,數(shù)據(jù)不會(huì)自動(dòng)出現(xiàn)在你的代碼里——它們散落在各處:

  • 業(yè)務(wù)系統(tǒng)導(dǎo)出的 CSV 文件
  • 同事發(fā)來(lái)的 Excel 表格
  • 公司數(shù)據(jù)庫(kù)中的 SQL 表
  • 網(wǎng)頁(yè)上的 JSON 數(shù)據(jù)
  • 傳感器記錄的 日志文件

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

比喻:如果把數(shù)據(jù)分析比作做菜,那么數(shù)據(jù)載入就是"采購(gòu)食材"。食材買(mǎi)錯(cuò)了(格式不對(duì))、買(mǎi)少了(數(shù)據(jù)不全)、或者買(mǎi)太多搬不動(dòng)(內(nèi)存溢出),這道菜就做不成了。

好消息是,pandas 提供了統(tǒng)一且強(qiáng)大的數(shù)據(jù)讀取接口。無(wú)論你面對(duì)什么格式的數(shù)據(jù),幾乎都能用 pd.read_xxx() 一行代碼搞定。但實(shí)際情況往往沒(méi)那么簡(jiǎn)單——編碼錯(cuò)誤、格式異常、文件過(guò)大……這些問(wèn)題才是真正考驗(yàn)?zāi)愎αΦ牡胤健?/p>

核心知識(shí)點(diǎn)講解

pandas 簡(jiǎn)介——數(shù)據(jù)分析的"瑞士軍刀"

pandas 是基于 NumPy 構(gòu)建的數(shù)據(jù)分析庫(kù),它的名字來(lái)源于 Panel Data(面板數(shù)據(jù))和 Python Data Science。

pandas 的兩個(gè)核心數(shù)據(jù)結(jié)構(gòu):

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

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

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

讀取 CSV 文件——最常見(jiàn)數(shù)據(jù)格式

基本讀取

CSV(Comma-Separated Values,逗號(hào)分隔值)是最常見(jiàn)的數(shù)據(jù)交換格式。

import pandas as pd

# 首先,我們創(chuàng)建一個(gè) CSV 文件用于演示
data = {
    '訂單ID': range(1, 11),
    '商品': ['手機(jī)', '電腦', '平板', '耳機(jī)', '鍵盤(pán)',
            '鼠標(biāo)', '顯示器', '音箱', '充電器', '數(shù)據(jù)線'],
    '價(jià)格': [2999, 5999, 1999, 199, 399,
            99, 1599, 499, 79, 29],
    '數(shù)量': [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數(shù)據(jù)形狀: {df_read.shape}")
print(f"數(shù)據(jù)類(lèi)型:\n{df_read.dtypes}")

read_csv 常用參數(shù)詳解

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

# 先寫(xiě)入文件
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=['編號(hào)', '姓名', '分?jǐn)?shù)', '等級(jí)', '評(píng)語(yǔ)'],
                  header=0))

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

# 4. 處理缺失值
print("\n4. 默認(rèn)缺失值處理:")
df = pd.read_csv('complex_data.csv')
print(df.isna().sum())  # 統(tǒng)計(jì)每列缺失值數(shù)量

# 5. 指定缺失值標(biāo)記
print("\n5. 自定義缺失值標(biāo)記:")
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)  # 應(yīng)該是 datetime64

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

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

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

# 10. 設(shè)置索引列
print("\n10. 設(shè)置索引列為訂單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 文件——職場(chǎng)中最常見(jiàn)的格式

基本讀取

import pandas as pd

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

# 寫(xiě)入 Excel(需要 openpyxl 庫(kù))
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讀取第一個(gè)工作表:")
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 讀取的實(shí)用技巧

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

# 2. 指定列的數(shù)據(jù)類(lèi)型
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)庫(kù)。安裝方法:pip install openpyxl

編碼問(wèn)題處理——數(shù)據(jù)載入的"頭號(hào)殺手"

什么是編碼問(wèn)題?

當(dāng)你嘗試讀取一個(gè) CSV 文件時(shí),可能會(huì)看到這樣的錯(cuò)誤:

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

這是因?yàn)槲募木幋a方式與讀取時(shí)指定的編碼不一致。

常見(jiàn)編碼方式

編碼說(shuō)明適用場(chǎng)景
UTF-8國(guó)際通用編碼,支持所有語(yǔ)言現(xiàn)代系統(tǒng)默認(rèn)
GBK / GB2312中文編碼Windows 中文系統(tǒng)
GB18030擴(kuò)展中文編碼生僻字支持
Latin-1西歐編碼歐洲語(yǔ)言
ASCII基礎(chǔ)編碼純英文

如何判斷文件編碼

# 方法1:使用 chardet 庫(kù)自動(dòng)檢測(cè)
# 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"檢測(cè)到的編碼: {result['encoding']}")
    print(f"置信度: {result['confidence']:.2%}")

# 方法2:用 pandas 的 errors 參數(shù)處理
# ignore:忽略無(wú)法解碼的字符
# replace:用 ? 替換無(wú)法解碼的字符
# 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("無(wú)法用任何編碼讀取文件")

df = read_with_encoding('sample_orders.csv')

實(shí)際解決方案

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

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

# 解決方案3:用 Notepad++ 或 VS Code 轉(zhuǎn)換文件編碼
# 打開(kāi)文件 -> 轉(zhuǎn)換為 UTF-8 -> 保存

最佳實(shí)踐:在團(tuán)隊(duì)協(xié)作中,統(tǒng)一規(guī)定所有數(shù)據(jù)文件使用 UTF-8 編碼,可以省去大量麻煩。

大數(shù)據(jù)分塊讀取——處理超內(nèi)存文件

什么時(shí)候需要分塊讀???

當(dāng)你的 CSV 文件有 10GB,而你的電腦只有 8GB 內(nèi)存時(shí),直接 pd.read_csv() 會(huì)失?。∕emoryError)。

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

import pandas as pd
import numpy as np

# 先創(chuàng)建一個(gè)大文件用于演示(模擬 100 萬(wàn)行數(shù)據(jù))
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} 行數(shù)據(jù)的文件")

方式1:使用 chunksize 參數(shù)

# 每次讀取 10 萬(wàn)行
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總行數(shù): {total_rows}")
print(f"value1 總和: {total_value1:,.2f}")
print(f"value2 總和: {total_value2:,.2f}")

方式2:分塊聚合(計(jì)算統(tǒng)計(jì)量)

# 計(jì)算大文件的整體統(tǒng)計(jì)信息
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())

# 計(jì)算均值和標(biāo)準(zhǔn)差
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("大文件統(tǒng)計(jì)信息:")
print(f"  value1: 均值={mean_v1:.2f}, 標(biāo)準(zhǔn)差={std_v1:.2f}, "
      f"范圍=[{stats['min_v1']:.2f}, {stats['max_v1']:.2f}]")
print(f"  value2: 均值={mean_v2:.2f}, 標(biāo)準(zhǔn)差={std_v2:.2f}, "
      f"范圍=[{stats['min_v2']:.2f}, {stats['max_v2']:.2f}]")

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

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

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

分塊讀取的注意事項(xiàng)

  1. 只讀需要的列:使用 usecols 參數(shù),減少內(nèi)存占用
  2. 指定數(shù)據(jù)類(lèi)型:使用 dtype 參數(shù),避免 pandas 自動(dòng)推斷導(dǎo)致的內(nèi)存浪費(fèi)
  3. 跳過(guò)不需要的行:使用 skiprows 參數(shù)
# 優(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é)省內(nèi)存
)

for chunk in optimized_chunks:
    # 處理每個(gè)塊
    pass

連接數(shù)據(jù)庫(kù)——從 SQL 讀取數(shù)據(jù)

SQLite——內(nèi)置數(shù)據(jù)庫(kù)(無(wú)需安裝服務(wù)器)

import pandas as pd
import sqlite3

# 創(chuàng)建 SQLite 數(shù)據(jù)庫(kù)
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
    )
''')

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

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

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

# 方式3:使用 read_sql_query(等價(jià)于 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 直接寫(xiě)入數(shù)據(jù)庫(kù)
df_new = pd.DataFrame({
    'id': [6, 7],
    'name': ['孫八', '周九'],
    'department': ['技術(shù)部', '市場(chǎng)部'],
    'salary': [16000, 13500],
    'hire_date': ['2023-05-10', '2023-08-20']
})
df_new.to_sql('employees', conn, if_exists='append', index=False)
print("\n4. 新增數(shù)據(jù)后:")
print(pd.read_sql('SELECT * FROM employees', conn))

# 關(guān)閉連接
conn.close()

MySQL 連接(需要安裝 pymysql)

# 注意:以下代碼需要 MySQL 服務(wù)器運(yùn)行
# 安裝: pip install pymysql

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

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

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

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

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

# 寫(xiě)入數(shù)據(jù)
df.to_sql('users_backup', engine, if_exists='replace', index=False)

# 復(fù)雜查詢
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://...。

其他數(shù)據(jù)格式讀取

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)

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

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

HTML 表格

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

# 這里用本地 HTML 演示
html_table = """
<table>
    <tr><th>姓名</th><th>成績(jī)</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)

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

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

import pandas as pd
import numpy as np
import sqlite3

# 場(chǎng)景:整合來(lái)自不同數(shù)據(jù)源的信息

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

# 數(shù)據(jù)源2:Excel 文件(績(jī)效數(shù)據(jù))
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='績(jī)效', index=False)

# 數(shù)據(jù)源3:SQLite 數(shù)據(jù)庫(kù)(薪資數(shù)據(jù))
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("多源數(shù)據(jù)整合分析")
print("=" * 50)

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

# 合并數(shù)據(jù)
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整合后的完整數(shù)據(jù):")
print(merged.to_string())

print("\n各季度平均績(jī)效:")
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"  獎(jiǎng)金均值: ¥{salary['bonus'].mean():,.0f}")
print(f"  總收入均值: ¥{merged['total_income'].mean():,.0f}")

conn.close()

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

import pandas as pd
import numpy as np

# 創(chuàng)建模擬日志文件(50 萬(wàn)行)
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} 行日志數(shù)據(jù)")

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

stats = {}
chunk_size = 50_000

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

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

    # 統(tǒng)計(jì)總用戶數(shù)
    stats['unique_users'] = len(chunk['user_id'].unique())

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

print("\n統(tǒng)計(jì)結(jié)果:")
for action, count in stats.items():
    print(f"  {action}: {count:,}" if action != 'unique_users'
          else f"  獨(dú)立用戶數(shù): {count:,}")

實(shí)戰(zhàn)練習(xí)

練習(xí)1:CSV 讀取與清洗

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

  • 包含空值
  • 包含重復(fù)行
  • 包含錯(cuò)誤類(lèi)型(如價(jià)格列出現(xiàn)了文本)

參考答案

import pandas as pd
import numpy as np

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

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

print("原始數(shù)據(jù):")
print(df)

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

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

# 3. 處理 price 列的文本(轉(zhuǎn)換為數(shù)字,無(wú)效的變 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清洗后數(shù)據(jù):")
print(df)

練習(xí)2:分塊統(tǒng)計(jì)

題目:用分塊讀取的方式,計(jì)算大文件中每個(gè) 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)

# 分塊統(tǒng)計(jì)
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("分類(lèi)統(tǒng)計(jì):")
for cat, stats in sorted(cat_stats.items()):
    mean = stats['sum'] / stats['count']
    print(f"  {cat}: 均值={mean:.2f}, 數(shù)量={stats['count']}")

練習(xí)3:數(shù)據(jù)庫(kù)查詢整合

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

參考答案

import pandas as pd
import sqlite3

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

# 創(chuàng)建客戶表
customers = pd.DataFrame({
    'customer_id': [1, 2, 3, 4, 5],
    'name': ['張三', '李四', '王五', '趙六', '錢(qián)七'],
    '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("客戶消費(fèi)分析:")
print(result.to_string())

conn.close()

本節(jié)總結(jié)

本節(jié)我們?nèi)鎸W(xué)習(xí)了從各種數(shù)據(jù)源讀取數(shù)據(jù)的方法。關(guān)鍵要點(diǎn):

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

編碼問(wèn)題是日常痛點(diǎn):Windows 中文系統(tǒng)導(dǎo)出的文件通常用 GBK 編碼。遇到問(wèn)題時(shí),嘗試 encoding='gbk'encoding='utf-8-sig'。使用 chardet 庫(kù)可以自動(dòng)檢測(cè)編碼。

分塊讀取解決大文件:當(dāng)文件超過(guò)內(nèi)存容量時(shí),使用 chunksize 參數(shù)分塊處理。配合 usecolsdtype 參數(shù)可以進(jìn)一步優(yōu)化內(nèi)存。

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

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

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

多種格式統(tǒng)一接口:無(wú)論是 CSV、Excel、JSON 還是數(shù)據(jù)庫(kù),pandas 都提供了 read_xxx() 的統(tǒng)一接口,降低了學(xué)習(xí)成本。

實(shí)用建議:在實(shí)際工作中,先花 5 分鐘檢查數(shù)據(jù)文件的編碼、格式和大小,再?zèng)Q定用哪種方式讀取。這一步可以避免后面 90% 的問(wèn)題。

下一節(jié)預(yù)告

恭喜!你已經(jīng)完成了第一階段的全部?jī)?nèi)容?;仡櫼幌履阏莆盏募寄埽?/p>

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

接下來(lái),我們將進(jìn)入第二階段,開(kāi)始學(xué)習(xí) pandas 的核心功能——數(shù)據(jù)處理與分析。你將掌握:

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

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

以上就是Pandas高效讀取CSV、Excel和SQL數(shù)據(jù)庫(kù)的數(shù)據(jù)的詳細(xì)內(nèi)容,更多關(guān)于Pandas數(shù)據(jù)讀取的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Python time庫(kù)的時(shí)間時(shí)鐘處理

    Python time庫(kù)的時(shí)間時(shí)鐘處理

    這篇文章主要介紹了Python time庫(kù)的時(shí)間時(shí)鐘處理,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-05-05
  • python編寫(xiě)網(wǎng)頁(yè)爬蟲(chóng)腳本并實(shí)現(xiàn)APScheduler調(diào)度

    python編寫(xiě)網(wǎng)頁(yè)爬蟲(chóng)腳本并實(shí)現(xiàn)APScheduler調(diào)度

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

    Pytorch建模過(guò)程中的DataLoader與Dataset示例詳解

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

    Python獲取接口數(shù)據(jù)的實(shí)現(xiàn)示例

    本文主要介紹了Python獲取接口數(shù)據(jù)的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-07-07
  • python實(shí)現(xiàn)帶聲音的摩斯碼翻譯實(shí)現(xiàn)方法

    python實(shí)現(xiàn)帶聲音的摩斯碼翻譯實(shí)現(xiàn)方法

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

    對(duì)python中Json與object轉(zhuǎn)化的方法詳解

    今天小編就為大家分享一篇對(duì)python中Json與object轉(zhuǎn)化的方法詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-12-12
  • wxPython窗體拆分布局基礎(chǔ)組件

    wxPython窗體拆分布局基礎(chǔ)組件

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

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

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

    pycharm通過(guò)anaconda安裝pyqt5的教程

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

    Python virtualenv虛擬環(huán)境實(shí)現(xiàn)過(guò)程解析

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

最新評(píng)論

民和| 都昌县| 蓝山县| 随州市| 丰原市| 兰坪| 苗栗县| 专栏| 景宁| 双辽市| 尉氏县| 定安县| 桑植县| 阜阳市| 石楼县| 临潭县| 沧源| 都匀市| 新乡市| 扶余县| 石嘴山市| 文山县| 舞阳县| 新乡县| 武清区| 黔西| 丹巴县| 锡林浩特市| 花莲市| 大冶市| 台东县| 常宁市| 车致| 稻城县| 阜新市| 瓮安县| 怀安县| 石泉县| 盘锦市| 桐柏县| 纳雍县|