活动公告

系统通知
05-18 21:22
系统通知
通知:本站资源由网友上传分享,如有违规等问题请到版务模块进行投诉,资源失效请在帖子内回复要求补档,会尽快处理!
10-23 09:31

如何使用pandas将DataFrame和Series高效转换为Python列表及常见问题解决方法

SunJu_FaceMall

3万

主题

2860

科技点

3万

积分

白金月票

碾压王

积分
32872

塔罗立华奏

<font color=白金月票" /> 发表于 2025-9-12 23:10:01 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
引言

Pandas是Python中最流行的数据分析库之一,它提供了强大的数据结构和数据分析工具。在数据处理过程中,DataFrame和Series是pandas中最常用的两种数据结构。然而,在某些情况下,我们需要将这些数据结构转换为Python原生的列表(list)类型,以便与其他库集成或进行特定的操作。本文将详细介绍如何高效地将DataFrame和Series转换为Python列表,并解决在此过程中可能遇到的常见问题。

pandas数据结构简介

在深入探讨转换方法之前,让我们简要回顾一下pandas中的两种主要数据结构:

DataFrame

DataFrame是pandas中的二维表格型数据结构,可以看作是由多个Series组成的字典。它具有行索引和列索引,并且可以存储不同类型的数据。
  1. import pandas as pd
  2. # 创建一个简单的DataFrame
  3. df = pd.DataFrame({
  4.     'Name': ['Alice', 'Bob', 'Charlie', 'David'],
  5.     'Age': [25, 30, 35, 40],
  6.     'City': ['New York', 'Los Angeles', 'Chicago', 'Houston']
  7. })
  8. print(df)
复制代码

Series

Series是pandas中的一维标记数组结构,类似于带有标签的NumPy数组。它由一组数据和与之相关的数据标签(索引)组成。
  1. # 创建一个简单的Series
  2. s = pd.Series([10, 20, 30, 40], index=['a', 'b', 'c', 'd'])
  3. print(s)
复制代码

将DataFrame转换为列表

将整个DataFrame转换为列表

有几种方法可以将整个DataFrame转换为列表:
  1. # 将整个DataFrame转换为列表的列表
  2. list_of_lists = df.values.tolist()
  3. print(list_of_lists)
  4. # 输出: [['Alice', 25, 'New York'], ['Bob', 30, 'Los Angeles'], ['Charlie', 35, 'Chicago'], ['David', 40, 'Houston']]
复制代码
  1. # 使用to_numpy()方法转换为NumPy数组,然后转换为列表
  2. list_of_lists = df.to_numpy().tolist()
  3. print(list_of_lists)
  4. # 输出: [['Alice', 25, 'New York'], ['Bob', 30, 'Los Angeles'], ['Charlie', 35, 'Chicago'], ['David', 40, 'Houston']]
复制代码

将DataFrame的列转换为列表
  1. # 将单列转换为列表
  2. name_list = df['Name'].tolist()
  3. print(name_list)
  4. # 输出: ['Alice', 'Bob', 'Charlie', 'David']
  5. # 或者使用点号表示法(仅适用于列名是有效的Python标识符的情况)
  6. age_list = df.Age.tolist()
  7. print(age_list)
  8. # 输出: [25, 30, 35, 40]
复制代码
  1. # 使用列索引将列转换为列表
  2. city_list = df.iloc[:, 2].tolist()  # 第3列(索引为2)
  3. print(city_list)
  4. # 输出: ['New York', 'Los Angeles', 'Chicago', 'Houston']
复制代码

将DataFrame的行转换为列表
  1. # 使用iterrows()将每一行转换为列表
  2. row_lists = []
  3. for index, row in df.iterrows():
  4.     row_lists.append(row.tolist())
  5. print(row_lists)
  6. # 输出: [['Alice', 25, 'New York'], ['Bob', 30, 'Los Angeles'], ['Charlie', 35, 'Chicago'], ['David', 40, 'Houston']]
复制代码
  1. # 使用itertuples()将每一行转换为命名元组,然后转换为列表
  2. row_lists = [list(row) for row in df.itertuples(index=False)]
  3. print(row_lists)
  4. # 输出: [['Alice', 25, 'New York'], ['Bob', 30, 'Los Angeles'], ['Charlie', 35, 'Chicago'], ['David', 40, 'Houston']]
复制代码
  1. # 使用values和列表推导式将每一行转换为列表
  2. row_lists = [list(row) for row in df.values]
  3. print(row_lists)
  4. # 输出: [['Alice', 25, 'New York'], ['Bob', 30, 'Los Angeles'], ['Charlie', 35, 'Chicago'], ['David', 40, 'Houston']]
复制代码

将Series转换为列表

基本转换方法
  1. # 将Series转换为列表
  2. s_list = s.tolist()
  3. print(s_list)
  4. # 输出: [10, 20, 30, 40]
复制代码
  1. # 使用list()构造函数将Series转换为列表
  2. s_list = list(s)
  3. print(s_list)
  4. # 输出: [10, 20, 30, 40]
复制代码
  1. # 使用values属性将Series转换为列表
  2. s_list = s.values.tolist()
  3. print(s_list)
  4. # 输出: [10, 20, 30, 40]
复制代码

保留索引的转换

如果需要在转换过程中保留索引信息:
  1. # 将Series转换为包含索引和值的元组列表
  2. indexed_list = list(zip(s.index, s.values))
  3. print(indexed_list)
  4. # 输出: [('a', 10), ('b', 20), ('c', 30), ('d', 40)]
  5. # 或者转换为字典列表
  6. dict_list = [{'index': idx, 'value': val} for idx, val in zip(s.index, s.values)]
  7. print(dict_list)
  8. # 输出: [{'index': 'a', 'value': 10}, {'index': 'b', 'value': 20}, {'index': 'c', 'value': 30}, {'index': 'd', 'value': 40}]
复制代码

高效转换技巧

使用to_numpy()方法

对于大型DataFrame,使用to_numpy()方法通常比直接访问values属性更高效:
  1. # 创建一个大型DataFrame
  2. import numpy as np
  3. large_df = pd.DataFrame(np.random.rand(100000, 5), columns=['A', 'B', 'C', 'D', 'E'])
  4. # 使用to_numpy()方法转换为NumPy数组,然后转换为列表
  5. %timeit large_list = large_df.to_numpy().tolist()
  6. # 输出: 平均执行时间(具体时间取决于硬件)
  7. # 使用values属性转换为列表
  8. %timeit large_list = large_df.values.tolist()
  9. # 输出: 平均执行时间(通常比to_numpy()稍慢)
复制代码

使用列表推导式

列表推导式通常比显式循环更高效:
  1. # 使用列表推导式将每一列转换为列表
  2. column_lists = [df[col].tolist() for col in df.columns]
  3. # 或者使用字典推导式
  4. column_dict = {col: df[col].tolist() for col in df.columns}
  5. print(column_dict)
  6. # 输出: {'Name': ['Alice', 'Bob', 'Charlie', 'David'], 'Age': [25, 30, 35, 40], 'City': ['New York', 'Los Angeles', 'Chicago', 'Houston']}
复制代码

使用itertuples()进行行迭代

对于行迭代,itertuples()比iterrows()更高效:
  1. # 使用itertuples()进行行迭代
  2. %timeit row_tuples = [tuple(row) for row in df.itertuples(index=False)]
  3. # 输出: 平均执行时间
  4. # 使用iterrows()进行行迭代
  5. %timeit row_tuples = [tuple(row) for index, row in df.iterrows()]
  6. # 输出: 平均执行时间(通常比itertuples()慢)
复制代码

使用apply方法

对于复杂的转换操作,可以使用apply方法:
  1. # 使用apply方法将每一行转换为列表
  2. row_lists = df.apply(lambda row: row.tolist(), axis=1).tolist()
  3. print(row_lists)
  4. # 输出: [['Alice', 25, 'New York'], ['Bob', 30, 'Los Angeles'], ['Charlie', 35, 'Chicago'], ['David', 40, 'Houston']]
复制代码

常见问题及解决方法

问题1:处理缺失值

在转换过程中,DataFrame或Series中的缺失值(NaN)可能会导致问题。
  1. # 创建包含缺失值的DataFrame
  2. df_with_nan = pd.DataFrame({
  3.     'A': [1, 2, np.nan, 4],
  4.     'B': [5, np.nan, 7, 8],
  5.     'C': [9, 10, 11, np.nan]
  6. })
  7. # 直接转换为列表
  8. list_with_nan = df_with_nan.values.tolist()
  9. print(list_with_nan)
  10. # 输出: [[1.0, 5.0, 9.0], [2.0, nan, 10.0], [nan, 7.0, 11.0], [4.0, 8.0, nan]]
复制代码

解决方法:
  1. # 方法1:使用fillna()填充缺失值
  2. filled_list = df_with_nan.fillna(0).values.tolist()
  3. print(filled_list)
  4. # 输出: [[1.0, 5.0, 9.0], [2.0, 0.0, 10.0], [0.0, 7.0, 11.0], [4.0, 8.0, 0.0]]
  5. # 方法2:使用dropna()删除包含缺失值的行
  6. dropped_list = df_with_nan.dropna().values.tolist()
  7. print(dropped_list)
  8. # 输出: [[1.0, 5.0, 9.0]]
  9. # 方法3:在转换为列表后处理缺失值
  10. import math
  11. processed_list = [[0 if math.isnan(x) else x for x in row] for row in df_with_nan.values.tolist()]
  12. print(processed_list)
  13. # 输出: [[1.0, 5.0, 9.0], [2.0, 0, 10.0], [0, 7.0, 11.0], [4.0, 8.0, 0]]
复制代码

问题2:处理大数据集的性能问题

对于大型DataFrame,转换为列表可能会消耗大量内存和时间。

解决方法:
  1. # 创建一个大型DataFrame
  2. large_df = pd.DataFrame(np.random.rand(1000000, 5), columns=['A', 'B', 'C', 'D', 'E'])
  3. # 方法1:分块处理
  4. chunk_size = 100000
  5. list_chunks = []
  6. for i in range(0, len(large_df), chunk_size):
  7.     chunk = large_df.iloc[i:i+chunk_size]
  8.     list_chunks.append(chunk.values.tolist())
  9. # 方法2:使用生成器表达式(适用于逐行处理)
  10. row_generator = (list(row) for row in large_df.itertuples(index=False))
  11. # 使用生成器(逐行处理,不一次性加载所有数据到内存)
  12. for i, row in enumerate(row_generator):
  13.     if i < 3:  # 只打印前3行作为示例
  14.         print(row)
  15.     else:
  16.         break
复制代码

问题3:处理多级索引

对于具有多级索引的DataFrame或Series,转换为列表需要特别注意索引结构的保留。
  1. # 创建具有多级索引的DataFrame
  2. index = pd.MultiIndex.from_tuples([('A', 1), ('A', 2), ('B', 1), ('B', 2)], names=['letter', 'number'])
  3. multi_df = pd.DataFrame({'X': [10, 20, 30, 40], 'Y': [50, 60, 70, 80]}, index=index)
  4. print(multi_df)
复制代码

解决方法:
  1. # 方法1:将索引转换为列,然后转换为列表
  2. multi_df_reset = multi_df.reset_index()
  3. list_with_index = multi_df_reset.values.tolist()
  4. print(list_with_index)
  5. # 输出: [['A', 1, 10, 50], ['A', 2, 20, 60], ['B', 1, 30, 70], ['B', 2, 40, 80]]
  6. # 方法2:保留索引结构
  7. indexed_list = []
  8. for idx, row in multi_df.iterrows():
  9.     indexed_list.append([idx[0], idx[1]] + row.tolist())
  10. print(indexed_list)
  11. # 输出: [['A', 1, 10, 50], ['A', 2, 20, 60], ['B', 1, 30, 70], ['B', 2, 40, 80]]
复制代码

问题4:处理数据类型转换问题

在转换过程中,可能会遇到数据类型不一致的问题。
  1. # 创建包含不同数据类型的DataFrame
  2. mixed_df = pd.DataFrame({
  3.     'int_col': [1, 2, 3, 4],
  4.     'float_col': [1.1, 2.2, 3.3, 4.4],
  5.     'str_col': ['a', 'b', 'c', 'd'],
  6.     'bool_col': [True, False, True, False]
  7. })
  8. # 直接转换为列表
  9. mixed_list = mixed_df.values.tolist()
  10. print(mixed_list)
  11. # 输出: [[1, 1.1, 'a', True], [2, 2.2, 'b', False], [3, 3.3, 'c', True], [4, 4.4, 'd', False]]
复制代码

解决方法:
  1. # 方法1:在转换前指定数据类型
  2. typed_list = mixed_df.astype({
  3.     'int_col': int,
  4.     'float_col': float,
  5.     'str_col': str,
  6.     'bool_col': bool
  7. }).values.tolist()
  8. print(typed_list)
  9. # 输出: [[1, 1.1, 'a', True], [2, 2.2, 'b', False], [3, 3.3, 'c', True], [4, 4.4, 'd', False]]
  10. # 方法2:在转换为列表后处理数据类型
  11. processed_list = []
  12. for row in mixed_df.values.tolist():
  13.     processed_row = [
  14.         int(row[0]),
  15.         float(row[1]),
  16.         str(row[2]),
  17.         bool(row[3])
  18.     ]
  19.     processed_list.append(processed_row)
  20. print(processed_list)
  21. # 输出: [[1, 1.1, 'a', True], [2, 2.2, 'b', False], [3, 3.3, 'c', True], [4, 4.4, 'd', False]]
复制代码

实际应用场景

场景1:数据可视化准备

许多Python可视化库(如Matplotlib、Seaborn)要求数据以列表形式提供。
  1. import matplotlib.pyplot as plt
  2. # 准备数据
  3. x = df['Age'].tolist()
  4. y = df['Name'].tolist()
  5. # 创建条形图
  6. plt.barh(y, x)
  7. plt.xlabel('Age')
  8. plt.ylabel('Name')
  9. plt.title('Age by Name')
  10. plt.show()
复制代码

场景2:与Web API交互

当需要将数据发送到Web API时,通常需要将DataFrame转换为JSON格式,而列表是JSON的基本组成部分。
  1. import json
  2. # 将DataFrame转换为字典列表,然后转换为JSON
  3. json_data = df.to_dict(orient='records')
  4. json_string = json.dumps(json_data)
  5. print(json_string)
  6. # 输出: '[{"Name":"Alice","Age":25,"City":"New York"},{"Name":"Bob","Age":30,"City":"Los Angeles"},{"Name":"Charlie","Age":35,"City":"Chicago"},{"Name":"David","Age":40,"City":"Houston"}]'
复制代码

场景3:机器学习特征准备

在机器学习中,特征通常需要以列表或NumPy数组的形式提供给模型。
  1. from sklearn.model_selection import train_test_split
  2. from sklearn.linear_model import LinearRegression
  3. # 准备特征和目标变量
  4. X = df[['Age']].values.tolist()  # 特征
  5. y = df['Age'].tolist()  # 目标变量
  6. # 分割数据集
  7. X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
  8. # 训练模型
  9. model = LinearRegression()
  10. model.fit(X_train, y_train)
  11. # 评估模型
  12. score = model.score(X_test, y_test)
  13. print(f"Model R^2 score: {score}")
复制代码

场景4:数据库操作

在与数据库交互时,通常需要将数据转换为列表形式。
  1. import sqlite3
  2. # 创建内存数据库
  3. conn = sqlite3.connect(':memory:')
  4. cursor = conn.cursor()
  5. # 创建表
  6. cursor.execute('''
  7. CREATE TABLE employees (
  8.     name TEXT,
  9.     age INTEGER,
  10.     city TEXT
  11. )
  12. ''')
  13. # 将DataFrame转换为列表并插入数据库
  14. employees = df.values.tolist()
  15. cursor.executemany('INSERT INTO employees VALUES (?, ?, ?)', employees)
  16. # 查询数据
  17. cursor.execute('SELECT * FROM employees')
  18. rows = cursor.fetchall()
  19. print(rows)
  20. # 输出: [('Alice', 25, 'New York'), ('Bob', 30, 'Los Angeles'), ('Charlie', 35, 'Chicago'), ('David', 40, 'Houston')]
  21. # 关闭连接
  22. conn.close()
复制代码

性能比较和最佳实践

性能比较

让我们比较不同方法的性能:
  1. import timeit
  2. # 创建测试DataFrame
  3. test_df = pd.DataFrame(np.random.rand(10000, 5), columns=['A', 'B', 'C', 'D', 'E'])
  4. # 测试不同方法的性能
  5. def method1():
  6.     return test_df.values.tolist()
  7. def method2():
  8.     return test_df.to_numpy().tolist()
  9. def method3():
  10.     return [list(row) for row in test_df.itertuples(index=False)]
  11. def method4():
  12.     return [row.tolist() for index, row in test_df.iterrows()]
  13. # 测量执行时间
  14. time1 = timeit.timeit(method1, number=100)
  15. time2 = timeit.timeit(method2, number=100)
  16. time3 = timeit.timeit(method3, number=100)
  17. time4 = timeit.timeit(method4, number=100)
  18. print(f"values.tolist(): {time1:.4f} seconds")
  19. print(f"to_numpy().tolist(): {time2:.4f} seconds")
  20. print(f"itertuples(): {time3:.4f} seconds")
  21. print(f"iterrows(): {time4:.4f} seconds")
复制代码

最佳实践

基于性能和可读性的考虑,以下是一些最佳实践:

1. 对于整个DataFrame转换为列表:使用df.values.tolist()或df.to_numpy().tolist(),这两种方法性能最佳。
2. 对于单列转换为列表:直接使用df['column_name'].tolist(),这是最直观和高效的方法。
3. 对于行转换为列表:使用列表推导式结合itertuples(),即[list(row) for row in df.itertuples(index=False)],这比使用iterrows()更高效。
4. 对于大型DataFrame:考虑分块处理或使用生成器,以避免内存问题。
5. 处理缺失值:在转换前使用fillna()或dropna()处理缺失值,以确保数据的一致性。
6. 保留索引信息:如果需要保留索引信息,考虑使用reset_index()或在转换过程中显式包含索引。

对于整个DataFrame转换为列表:使用df.values.tolist()或df.to_numpy().tolist(),这两种方法性能最佳。

对于单列转换为列表:直接使用df['column_name'].tolist(),这是最直观和高效的方法。

对于行转换为列表:使用列表推导式结合itertuples(),即[list(row) for row in df.itertuples(index=False)],这比使用iterrows()更高效。

对于大型DataFrame:考虑分块处理或使用生成器,以避免内存问题。

处理缺失值:在转换前使用fillna()或dropna()处理缺失值,以确保数据的一致性。

保留索引信息:如果需要保留索引信息,考虑使用reset_index()或在转换过程中显式包含索引。

总结

本文详细介绍了如何将pandas中的DataFrame和Series高效转换为Python列表,包括基本转换方法、高效转换技巧、常见问题及解决方法,以及实际应用场景。通过掌握这些技巧,你可以更加灵活地处理数据转换任务,提高数据分析的效率和准确性。

在实际应用中,选择合适的转换方法取决于你的具体需求、数据大小和性能要求。希望本文能帮助你更好地理解和使用pandas数据结构转换为Python列表的方法,并在实际工作中取得更好的效果。
「七転び八起き(ななころびやおき)」
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则