更新:@AntonvBR的答案有效。非常感谢!
此外,由于这里要处理的是茶列中的每个元素,因此实际上是Series
而不是DataFrame
。因此,我猜.apply()
的工作原理与.map()
相同。
原始问题:
很抱歉,我不知道如何表达自己的更好,但这是这个问题:
假设有两个DataFrame,即STUDENT和TEACHER。
STUDENT DataFrame有两列: ID 和 home (她或他来自哪个城市)。当然,这些ID是唯一。
另一方面,TEACHER DataFrame还具有两列: ID 和学生ID列表(在班级中)。
这两个是这样的:
In [72]: stu
Out[72]:
ID home
0 1 XA
1 2 BJ
2 3 TJ
3 4 JN
4 5 CQ
5 6 SH
6 7 GZ
7 8 BJ
8 9 TJ
9 10 BJ
In [75]: tea
Out[75]:
ID stu
0 1 [1, 2, 3]
1 2 [2, 7, 8, 9]
2 3 [4, 5, 6, 10]
现在我想在TEACHER上添加第三列,其中也包含教师学生的“家” 的列表,并且应该没有重复在每个列表中。
所以我想知道如何以熊猫的方式看起来整洁干净?
我是熊猫和SQL的新手,我想出的唯一方法是在每一行上进行迭代,并在每个列表上进行迭代,然后从另一个DataFrame中获取值并一个接一个地追加... / p>
请给我一些建议或提示。
非常感谢您。
答案 0 :(得分:0)
好的,这是一个很简单的问题,可以通过多种方式解决。无论如何,
stu
列中有对象的事实使事情变得有些复杂。
考虑以下示例:
import pandas as pd
stu = pd.DataFrame({
'ID': [1,2],
'home': ['XA','BJ']
})
tea = pd.DataFrame({
'ID': [1,2],
'stu': [[1],[1,2]]
})
m = stu.set_index('ID')['home'] # <-- this here creates a map between stu id and stu home
tea['stu_home'] = tea['stu'].apply(lambda x: [m.get(i,'N/A') for i in x])
print(tea)
返回:
ID stu stu_home
0 1 [1] [XA]
1 2 [1, 2] [XA, BJ]
简短说明:
应用于数据框列的.apply()
将获取所有元素并为每个元素执行一个函数(在这种情况下,这意味着行值)。
通过传递lambda函数,表达式变得非常紧凑。
我们想为每个行元素中的每个元素找到学生的家。为此,我们可以使用列表理解并从我们在上一行中创建的字典(映射)中获取值。 m.get(i, 'N/A')
将获取每个值并返回N/A
(如果未找到)。这使脚本更具“崩溃安全性”。
希望这对您有所帮助!