A pandasDataFrame是一种二维标记数据结构,可以容纳整数、字符串、浮点等不同类型的数据。
在本教程中,我们将揭示创建 pandas DataFrame 的几种不同方法,使用列表、字典、系列等数据结构,NumPy 数组,甚至其他 DataFrame。
从列表创建 Pandas DataFrame
从列表创建 pandas 数据框是一种基本且简单的方法。您可以通过多种方式做到这一点。
简单列表
考虑以下示例,我们使用单个列表来创建 DataFrame:
import pandas as pd
# create a simple list
data = ['Adam', 'Tom', 'Lisa', 'Dan', 'Eve', 'Frank', 'Grace', 'Heidi', 'Ivan', 'Judy']
# create dataframe from list
df = pd.DataFrame(data, columns=['Name'])
print(df)
Output:
Name
0 Adam
1 Tom
2 Lisa
3 Dan
4 Eve
5 Frank
6 Grace
7 Heidi
8 Ivan
9 Judy
在上面的代码片段中,我们从名为的列表中创建一个 pandas 数据框data
其中有 10 个字符串元素。
通过将此列表传递给 DataFrame 构造函数,pd.DataFrame()
,我们告诉 pandas 创建一个包含一列的 DataFrame。我们还通过提供列名称“Name”columns
范围。
嵌套列表或列表列表
接下来,我们来看看如何使用列表列表创建 DataFrame:
# create a list of lists
data = [['Adam', 25], ['Tom', 30], ['Lisa', 35], ['Dan', 40], ['Eve', 45], ['Frank', 50], ['Grace', 55], ['Heidi', 60], ['Ivan', 65], ['Judy', 70]]
# create dataframe from list of lists
df = pd.DataFrame(data, columns=['Name', 'Age'])
print(df)
Output:
Name Age
0 Adam 25
1 Tom 30
2 Lisa 35
3 Dan 40
4 Eve 45
5 Frank 50
6 Grace 55
7 Heidi 60
8 Ivan 65
9 Judy 70
在此代码片段中,我们从列表列表创建一个 DataFrame,其中每个子列表都可以视为生成的 DataFrame 中的一行。
参数columns
用于显式指定列名称“Name”和“Age”。
词典列表
从列表创建 pandas 数据框的更灵活的方法是使用字典列表:
# create a list of dictionaries
data = [
{'Name': 'Adam', 'Age': 25},
{'Name': 'Tom', 'Age': 30},
{'Name': 'Lisa', 'Age': 35},
{'Name': 'Dan', 'Age': 40},
{'Name': 'Eve', 'Age': 45},
{'Name': 'Frank', 'Age': 50},
{'Name': 'Grace', 'Age': 55},
{'Name': 'Heidi', 'Age': 60},
{'Name': 'Ivan', 'Age': 65},
{'Name': 'Judy', 'Age': 70},
]
# create dataframe from list of dictionaries
df = pd.DataFrame(data)
print(df)
Output:
Name Age
0 Adam 25
1 Tom 30
2 Lisa 35
3 Dan 40
4 Eve 45
5 Frank 50
6 Grace 55
7 Heidi 60
8 Ivan 65
9 Judy 70
在本例中,我们从字典列表创建了一个 DataFrame。列表中的每个字典代表 DataFrame 中的一行。
字典键成为列名。如果字典中缺少键,pandas 会用以下内容填充该空间NaN
values.
从字典创建数据框
您可以使用不同结构的字典:列表字典、系列字典或字典字典。
列表词典
创建 DataFrame 的常见方法是使用列表字典:
data = {
'Name': ['Adam', 'Tom', 'Lisa', 'Dan', 'Eve', 'Frank', 'Grace', 'Heidi', 'Ivan', 'Judy'],
'Age': [25, 30, 35, 40, 45, 50, 55, 60, 65, 70]
}
df = pd.DataFrame(data)
print(df)
Output:
Name Age
0 Adam 25
1 Tom 30
2 Lisa 35
3 Dan 40
4 Eve 45
5 Frank 50
6 Grace 55
7 Heidi 60
8 Ivan 65
9 Judy 70
在上面的代码中,我们将一个字典传递给 DataFrame 构造函数。每个键值对对应一列;键成为列名,值构成列中的数据。
系列词典
您还可以从 Series 字典创建 DataFrame。字典中的每个系列在 DataFrame 中形成一列:
data = {
'Name': pd.Series(['Adam', 'Tom', 'Lisa', 'Dan', 'Eve', 'Frank', 'Grace', 'Heidi', 'Ivan', 'Judy']),
'Age': pd.Series([25, 30, 35, 40, 45, 50, 55, 60, 65, 70])
}
df = pd.DataFrame(data)
print(df)
Output:
Name Age
0 Adam 25
1 Tom 30
2 Lisa 35
3 Dan 40
4 Eve 45
5 Frank 50
6 Grace 55
7 Heidi 60
8 Ivan 65
9 Judy 70
在这种情况下,字典中的每个系列代表一列。字典的键用作列标签。该索引是所有系列索引的并集。
字典字典(嵌套字典)
从字典创建数据帧的另一个示例是传递字典的字典。在这种情况下,每个字典代表一列:
data = {'Adam': {'Age': 25}, 'Tom': {'Age': 30}, 'Lisa': {'Age': 35}, 'Dan': {'Age': 40}, 'Eve': {'Age': 45}, 'Frank': {'Age': 50}, 'Grace': {'Age': 55}, 'Heidi': {'Age': 60}, 'Ivan': {'Age': 65}, 'Judy': {'Age': 70}}
df = pd.DataFrame(data)
print(df)
Output:
Adam Tom Lisa Dan Eve Frank Grace Heidi Ivan Judy
Age 25 30 35 40 45 50 55 60 65 70
外部字典的键用作列标签。
内部字典的键作为行标签,如果内部字典之间有公共键,则成为行标签;如果没有,pandas 会填写NaN
缺失数据的值。
但是,如果您想要与前面的示例相同的输出,您可以使用 Transpose 转换数据,如下所示:
data = {'Adam': {'Age': 25}, 'Tom': {'Age': 30}, 'Lisa': {'Age': 35}, 'Dan': {'Age': 40}, 'Eve': {'Age': 45}, 'Frank': {'Age': 50}, 'Grace': {'Age': 55}, 'Heidi': {'Age': 60}, 'Ivan': {'Age': 65}, 'Judy': {'Age': 70}}
df = pd.DataFrame(data).T.reset_index()
df.columns = ['Name', 'Age']
print(df)
Output:
Name Age
0 Adam 25
1 Tom 30
2 Lisa 35
3 Dan 40
4 Eve 45
5 Frank 50
6 Grace 55
7 Heidi 60
8 Ivan 65
9 Judy 70
The T
转置 DataFrame(切换轴)并且reset_index
使索引成为一列。
单系列
从单个 Series 创建 DataFrame 非常简单:
data = pd.Series(['Adam', 'Tom', 'Lisa', 'Dan', 'Eve', 'Frank', 'Grace', 'Heidi', 'Ivan', 'Judy'], name='Name')
df = pd.DataFrame(data)
print(df)
Output:
Name
0 Adam
1 Tom
2 Lisa
3 Dan
4 Eve
5 Frank
6 Grace
7 Heidi
8 Ivan
9 Judy
在上面的代码中,我们从 Series 创建了一个 DataFrame,其中 Series 形成了 DataFrame 中的一列。系列的名称用作列名称。
多系列
创建 DataFrame 的另一个示例是从多个 Series 创建它:
series_1 = pd.Series(['Adam', 'Tom', 'Lisa', 'Dan', 'Eve', 'Frank', 'Grace', 'Heidi', 'Ivan', 'Judy'], name='Name')
series_2 = pd.Series([25, 30, 35, 40, 45, 50, 55, 60, 65, 70], name='Age')
df = pd.DataFrame([series_1, series_2]).transpose()
print(df)
Output:
Name Age
0 Adam 25
1 Tom 30
2 Lisa 35
3 Dan 40
4 Eve 45
5 Frank 50
6 Grace 55
7 Heidi 60
8 Ivan 65
9 Judy 70
在此示例中,我们通过首先创建系列列表然后转置 DataFrame,从两个 Series 创建一个 DataFrame。
每个系列的名称成为 DataFrame 中的列名称。
一维 NumPy 数组
以下是如何从一维 NumPy 数组创建 DataFrame:
import numpy as np
import pandas as pd
data = np.array(['Adam', 'Tom', 'Lisa', 'Dan', 'Eve', 'Frank', 'Grace', 'Heidi', 'Ivan', 'Judy'])
df = pd.DataFrame(data, columns=['Name'])
print(df)
Output:
Name
0 Adam
1 Tom
2 Lisa
3 Dan
4 Eve
5 Frank
6 Grace
7 Heidi
8 Ivan
9 Judy
在上面的代码片段中,我们将一维 NumPy 数组传递给 DataFrame 构造函数。
这将创建一个具有单列的 DataFrame。我们使用以下方式提供列名称“Name”columns
范围。
二维 NumPy 数组
让我们看看如何从二维 NumPy 数组创建 DataFrame:
data = np.array([['Adam', 25], ['Tom', 30], ['Lisa', 35], ['Dan', 40], ['Eve', 45], ['Frank', 50], ['Grace', 55], ['Heidi', 60], ['Ivan', 65], ['Judy', 70]])
df = pd.DataFrame(data, columns=['Name', 'Age'])
print(df)
Output:
Name Age
0 Adam 25
1 Tom 30
2 Lisa 35
3 Dan 40
4 Eve 45
5 Frank 50
6 Grace 55
7 Heidi 60
8 Ivan 65
9 Judy 70
在此示例中,我们将二维 NumPy 数组传递给 DataFrame 构造函数。这将创建一个 DataFrame,其中每个内部数组都被视为一行。
我们通过以下方式指定列名称“Name”和“Age”columns
范围。
多维 NumPy 数组
从多维数组创建 DataFrame 需要特殊考虑,因为 DataFrame 是二维结构。
例如,您可以通过创建多索引 DataFrame 来处理三维数组。
这是一个例子:
import numpy as np
import pandas as pd
# create a three-dimensional numpy array
data = np.random.randint(1, 10, (2, 10, 3)) # 2 sets, 10 rows, 3 columns
# create multi-index
index = pd.MultiIndex.from_product([range(s)for s in data.shape], names=['Set', 'Row', 'Column'])
# create dataframe from 3d numpy array
df = pd.DataFrame({'Value': data.flatten()}, index=index)
print(df)
Output:
Value
Set Row Column
0 0 0 3
1 5
2 6
1 0 4
1 2
... ...
1 8 2 7
9 0 3
1 9
2 4
在此示例中,我们创建一个具有随机值的三维 NumPy 数组。
由于 DataFrame 是二维结构,我们必须使用以下方法展平 3D 数组flatten()
方法,然后创建一个 MultiIndex DataFrame,显示原始 3D 数组的“集合”、“行”和“列”。
您需要决定如何表示数据,因为 pandas DataFrame 本质上是一个 2D 结构。
请注意,此方法也可以处理三个以上的维度。
然而,有很多方法可以转换NumPy 数组到 Pandas DataFrame.
使用 copy() 从其他 DataFrame 创建 DataFrame
我们可以使用以下命令创建一个新的 DataFrame,它是现有 DataFrame 的副本copy()
method.
如果您想创建一个新的 DataFrame 来进行操作而不影响原始数据,这非常有用。
具体做法如下:
data = {
'Name': ['Adam', 'Tom', 'Lisa', 'Dan', 'Eve', 'Frank', 'Grace', 'Heidi', 'Ivan', 'Judy'],
'Age': [25, 30, 35, 40, 45, 50, 55, 60, 65, 70]
}
df1 = pd.DataFrame(data)
# create a new dataframe that is a copy of df1
df2 = df1.copy()
print(df2)
Output:
Name Age
0 Adam 25
1 Tom 30
2 Lisa 35
3 Dan 40
4 Eve 45
5 Frank 50
6 Grace 55
7 Heidi 60
8 Ivan 65
9 Judy 70
在此示例中,我们创建一个原始 DataFramedf1
一些数据。然后我们使用copy()
方法来创建df2
,这是一个独立的副本df1
。所做的任何更改df2
不会影响df1
,反之亦然。
使用子集选择创建数据框
您可以从现有 DataFrame 的子集创建新的 DataFrame。这可以通过选择某些行、列或两者来完成。
具体做法如下:
# create an original dataframe
data = {
'Name': ['Adam', 'Tom', 'Lisa', 'Dan', 'Eve', 'Frank', 'Grace', 'Heidi', 'Ivan', 'Judy'],
'Age': [25, 30, 35, 40, 45, 50, 55, 60, 65, 70],
'Gender': ['F', 'M', 'M', 'M', 'F', 'M', 'F', 'F', 'M', 'F']
}
df = pd.DataFrame(data)
# create a new dataframe from a subset of the original dataframe
subset_df = df[df['Gender'] == 'F']
print(subset_df)
Output:
Name Age Gender
0 Adam 25 F
4 Eve 45 F
6 Grace 55 F
7 Heidi 60 F
9 Judy 70 F
在此示例中,我们从 DataFrame 开始df
包含“姓名”、“年龄”和“性别”列。然后我们创建一个新的DataFramesubset_df
仅包含“性别”为“F”的行。
这是使用布尔索引完成的,其中df['Gender'] == 'F'
返回一个布尔系列True
对于“性别”为“F”的所有行。该系列用于选择行的子集df
.
从文本创建数据框(使用正则表达式)
我们可以通过使用正则表达式解析和提取所需的数据,从文本数据创建一个 DataFrame,无论分隔符是什么:
import re
# sample text data
text = '''
Adam is 25 years old
Tom is 30 years old
Lisa is 35 years old
Dan is 40 years old
Eve is 45 years old
Frank is 50 years old
Grace is 55 years old
Heidi is 60 years old
Ivan is 65 years old
Judy is 70 years old
'''
# use regex to extract names and ages
names = re.findall(r'(\w+) is \d+ years old', text)
ages = re.findall(r'\w+ is (\d+) years old', text)
# create dataframe from the extracted data
df = pd.DataFrame({
'Name': names,
'Age': ages
})
print(df)
Output:
Name Age
0 Adam 25
1 Tom 30
2 Lisa 35
3 Dan 40
4 Eve 45
5 Frank 50
6 Grace 55
7 Heidi 60
8 Ivan 65
9 Judy 70
在此示例中,我们从包含文本数据的字符串开始。我们使用re.findall()
使用正则表达式的函数从文本中提取姓名和年龄。
提取的姓名和年龄用于创建数据帧。
注意re.findall()
返回列表,这些列表用作传递给 DataFrame 构造函数的字典中的值。
要避免的常见错误
创建 DataFrame 是 pandas 中的一项基本操作,有时由于各种原因可能会很棘手。您应该注意一些常见的陷阱。
意识到这些错误将提高您的 DataFrame 创建效率并减少调试时间。
数据和列长度不匹配
一个常见的错误是尝试创建一个 DataFrame,其中传递的数据长度与指定列的长度不匹配。
所有输入数据和列的长度必须相等,否则 pandas 将引发错误。
import pandas as pd
try:
df = pd.DataFrame({
'Name': ['Adam', 'Tom', 'Lisa'], # 3 items
'Age': [25, 30] # 2 items
})
except ValueError as e:
print(e)
这将引发一个ValueError
这就是说“数组的长度必须相同”。因此,在创建 DataFrame 时,请始终确保数据数组和列的长度相同。
不指定列表列表的列名称
当从列表列表创建 DataFrame 而不指定列时,pandas 将自动分配从 0 开始的整数列名称。这可能不是您想要的。
data = [['Adam', 25], ['Tom', 30], ['Lisa', 35]]
df = pd.DataFrame(data)
print(df)
这将创建一个包含名为 0 和 1 的列的 DataFrame。为避免这种情况,请在创建 DataFrame 时始终指定列名称。
数据类型不一致
DataFrame 可以保存不同的数据类型,但是当单个列中的数据类型不一致时,可能会导致意外结果。
例如,如果您有一列主要是整数,但只有一行包含字符串,则 pandas 会将整个列向上转换为对象数据类型。
import pandas as pd
data = {
'Name': ['Adam', 'Tom', 'Lisa', 'Dan', 'Eve'],
'Age': [25, 'Thirty', 35, 40, 45]
}
df = pd.DataFrame(data)
print(df)
print("\nData types:")
print(df.dtypes)
Output:
Name Age
0 Adam 25
1 Tom Thirty
2 Lisa 35
3 Dan 40
4 Eve 45
Data types:
Name object
Age object
dtype: object
在此示例中,大多数“Age”值都是整数,但由于一个值(“Thirty”)是一个字符串,pandas 会自动将整个“Age”列向上转换为object
.
最好为每列保持统一的数据类型,以提高存储和操作的效率。
深复制与浅复制
当从另一个 DataFrame 创建 DataFrame 时,一个常见的错误是忽略了这样一个事实:默认情况下,pandas 返回一个视图(浅拷贝)而不是数据的副本。
这意味着如果您基于另一个 DataFrame 创建一个新的 DataFrame 并修改它,您最终将修改原始 DataFrame。
为了避免这种情况,请使用copy()
如果您不希望新的 DataFrame 链接到原始 DataFrame,则在从另一个 DataFrame 创建 DataFrame 时使用该函数。
了解这些常见错误可以帮助您更有效地使用 pandas DataFrame。请记住,熟能生巧,因此您使用这些结构的次数越多,您的效率就会越高。
这要花一条胳膊和一条腿
在我作为一名 Python 开发人员的这些年里,我参与过许多复杂的项目,但当我们讨论 Pandas 中的 DataFrame 创建时,有一个特别突出。
该项目是为埃及的一家大型电信公司服务的,涉及分析用户行为、网络性能和人口统计的大量数据集,以更好地定制他们的服务和营销工作。
我们正在处理数 TB 的数据,其中大部分数据是从网络传感器和用户行为日志实时传输的。
每天都会产生大量数据,数据量之大给处理和分析带来了挑战。我们使用 Python 的 Pandas 库,因为它具有处理大型数据集和执行复杂数据操作的卓越能力。
一天晚上,当我正在努力进行一项特别棘手的分析时,我的脚本开始抛出 ValueErrors。 “数组的长度必须相同”。
我以前就见过这样的情况,但在这种情况下却出乎意料。我的所有数据都应该来自我们的数据管道的完整记录。
我开始调试,首先检查传入的最新数据块。结果发现我们的一个数据源出现了问题——故障的网络传感器正在发送不完整的数据。
对于大多数记录,有七个数据点,但有故障的传感器只发送六个数据点。
当我尝试创建列长度不匹配的 DataFrame 时,这导致“数组必须具有相同的长度”错误。
一旦发现问题,我就采取了两管齐下的方法来避免将来再出现此类问题。
首先,我在尝试创建 DataFrame 之前开始实施数据验证检查。
这些检查确保每个记录在尝试将其加载到 DataFrame 之前具有正确数量的数据点。这使我能够从源头发现数据的任何问题。
其次,我在 DataFrame 创建脚本中添加了更强大的错误处理。
现在,如果数据存在导致 ValueError 的问题,脚本将记录有问题的数据并继续处理数据集的其余部分。
这样,单个有问题的记录就不会停止对数百万条良好记录的分析。
这一事件提醒我们,在处理现实世界的数据时,为异常和错误做好准备至关重要。虽然 Pandas 使数据操作变得更容易,但您始终必须对意外情况进行预测和计划。