如果我们有一个(更大的)数据框,显示旅行中个人(行)访问的状态:
df = pd.DataFrame({'states_visited': [['NY', 'CA'], 'CA', 'CA']}, index = ['John', 'Mary', 'Joe'])
states_visited
John [NY, CA]
Mary CA
Joe CA
因为
states_visited
列具有
list
类型的值,我们不能使用通常的pandas方法,例如:
df['states_visited'].unique()
获得预期结果:
[[NY, CA] , CA]
例如,如果我们想知道一起访问了哪些州(纽约州和加利福尼亚州)以及分别访问了哪些州(加利福尼亚州),这就是我们所需要的。
相反,我们得到
TypeError: unhashable type: 'list'
同样,我们无法
df['states_visited'].str.contains('NY')
知道谁在他/她的旅行中访问了纽约(它将返回
NaN
约翰)。为了实现这一点,我们必须经历类似的事情:
df['states_visited'].explode()
.dropna()
.str.contains('NY')
.groupby(level=0).any()
.astype(float)
)
所以,如果 pandas 不喜欢嵌套数据,那么在 pandas 数据框/系列中拥有类似列表的值的正确方法是什么(不是简单的字典,因为该示例数据是更大数据框的一部分)?
在 Pandas 中处理数据框单元格中的列表可能会很棘手,因为许多 Pandas 函数并非旨在直接处理此类数据。但是,有一些方法可以有效地处理此类场景,而无需像在示例中那样进行复杂的操作。
1. 针对唯一列表:
-
将列表转换为元组:
unique
函数需要可哈希的项目,而列表不是。将列表转换为元组可以解决此问题,因为元组是不可变的,因此是可哈希的。
df['states_visited'] = df['states_visited'].apply(lambda x: tuple(x) if isinstance(x, list) else x)
unique_states = df['states_visited'].unique()
print(unique_states)
输出:
array([('NY', 'CA'), 'CA'], dtype=object)
2. 针对包含特定州:
-
使用
apply
和列表推导: 可以使用apply
在states_visited
列上循环,并使用列表推导来检查列表中是否存在 'NY'。
df['visited_NY'] = df['states_visited'].apply(lambda x: 'NY' in x if isinstance(x, list) else 'NY' == x)
print(df)
输出:
states_visited visited_NY
John [NY, CA] True
Mary CA False
Joe CA False
关于数据结构:
虽然这些方法适用于的用例,但对于更大的数据集,在 Pandas 数据框中存储嵌套列表并不是最有效或最便捷的方法。以下是一些替代方案:
-
使用
explode
并创建虚拟变量:
df = df.explode('states_visited')
df = pd.crosstab(df.index, df.states_visited).astype(bool).reset_index()
print(df)
输出:
index CA NY
0 Joe True False
1 John True True
2 Mary True False
此方法将每种状态表示为单独的列,当需要频繁地对各个状态执行操作时,这非常有用。
- 使用其他数据结构,例如字典或列表列表: 如果处理的是更复杂的关系(例如,每个州的访问日期),将此信息存储在单独的字典或列表中,然后使用这些数据结构创建单独的数据框可能更有意义。
选择最佳方法取决于的具体数据大小、需要执行的操作类型以及的性能考虑因素。
标签:python,pandas From: 78773065