取两个集合 'A' 和 'B' ,如何在 pandas 中创建一个集合 C= A minus B
Take two sets 'A' and 'B' , how to create a set C= A minus B in pandas
假设我有两个集合 'A' 和 'B',我如何在 pandas 中创建集合 C= A 减去 B。这里 A 和 B 是数据帧。 A 是一个包含名字和姓氏作为多索引的数据框。 B 有整数作为索引。名字和姓氏是 B 中的列。
我尝试通过 A['index']=A.index 将 A 的多索引转换为 A 的列,后来尝试合并 B 并且 A.But 它不起作用。
甲:
乙:
B 的列(f_Name 和 l_name)是 A 的多索引。
我想要 A 中 f_name 和 l_name 不存在于 B 中的所有行作为输出。我试过以下代码:
A['index']=A.index
my_df=pd.merge(A,B,left_on=['F_name','L_name'],right_index=True,how='left']
ans_df=A[~A.index.isin(my_df.index)]
但是 len(and_df) 与 len(A) 相同,这是不正确的。 ans_df的长度应该小于A的长度,因为B中只有f_name和l_name
使用假列的解决方案
免责声明:您可以在下面找到 "fake column" 方法的示例,该方法可能不适用于具有许多复杂类型的匹配列的大型数据帧。此外,我更喜欢使用简单的索引并将尽可能多的数据放入列而不是索引中。
那么,让我们创建两个数据集:A 将包含几个随机的恶搞之家角色,B 将包含几个恶搞之家家庭成员。希望您熟悉这部精彩的电视剧! :)
# Create a DF A with some Quahog Family guy citizens (with multiindex)
multiindexA = pd.MultiIndex.from_tuples([["Peter","Griffin"],["Glenn","Quagmire"],["Joe","Swanson"],["Cleveland","Brown"],["Brian","Griffin"],["Stewie","Griffin"],["Lois","Griffin"]],names=["Name","Surname"])
A=pd.DataFrame([40,35,38,45,8,2,35],index=multiindexA, columns=["Age"])
print A
Age
Name Surname
Peter Griffin 40
Glenn Quagmire 35
Joe Swanson 38
Cleveland Brown 45
Brian Griffin 8
Stewie Griffin 2
Lois Griffin 35
# Create a DF B with some Family guy inner family members (with simple simple index)
B = pd.DataFrame(data=[["Peter","Griffin",40],["Lois","Griffin",35],["Brian","Griffin",8],["Stewie","Griffin",2]], columns=["Name","Surname","Age"])
print B
Name Surname Age
0 Peter Griffin 40
1 Lois Griffin 35
2 Brian Griffin 8
3 Stewie Griffin 2
让我们找出不属于格里芬家族成员的恶搞之家角色。首先,我们将使用 reset_index
将数据帧规范化为相同的结构,因为这将使我们的生活更轻松:
# Reset index to move multiindex into columns in order to normalize dataframes
A = A.reset_index()
print A
Name Surname Age
0 Peter Griffin 40
1 Glenn Quagmire 35
2 Joe Swanson 38
3 Cleveland Brown 45
4 Brian Griffin 8
5 Stewie Griffin 2
6 Lois Griffin 35
由于您在两个(或更多列)上进行匹配,一个(可能是脏的和内存浪费的)解决方案可能是 通过将有趣的列组合成一个来创建假索引列具有 .apply(lambda x: ...)
功能。请记住,您必须使用 .astype(str)
.:
将任何非字符串字段转换为字符串
#Create a new dummy column by merging all matching columns into one (in both dataframes!)
A["fake_index_col"]=A[["Name","Surname","Age"]].astype(str).apply(lambda x: "".join(x),axis=1)
B["fake_index_col"]=B[["Name","Surname","Age"]].astype(str).apply(lambda x: "".join(x),axis=1)
这将向两个数据帧添加一个虚拟列,所有匹配数据将被压缩到一个字段中。
Name Surname Age fake_index_col
0 Peter Griffin 40 PeterGriffin40
1 Glenn Quagmire 35 GlennQuagmire35
2 Joe Swanson 38 JoeSwanson38
3 Cleveland Brown 45 ClevelandBrown45
4 Brian Griffin 8 BrianGriffin8
5 Stewie Griffin 2 StewieGriffin2
6 Lois Griffin 35 LoisGriffin35
这将使您可以轻松地应用 isin
函数的反函数来找到不是狮鹫的 Quahog 公民。最后删除假列 and/or 重新创建多索引以保留数据帧的初始状态。
C = A[~A["fake_index_col"].isin(B["fake_index_col"])]
del C["fake_index_col"]
print C
Name Surname Age
1 Glenn Quagmire 35
2 Joe Swanson 38
3 Cleveland Brown 45
这是数据帧 A 和 B
import pandas as pd
import numpy as np
A
Age Gender
F_name L_name
Josh Crammer 25 M
John Smith 29 M
Mellisa Simpson 32 F
Ahemed Khan 26 M
Frank J 25 M
Charles Brown 26 M
William Gibson 26 M
B
F_name L_name
0 Josh Crammer
2 Mellisa Simpson
4 Frank J
5 Charles Brown
6 William Gibson
我们可以做的是重置 A 的索引并像这样在适当的位置创建列。
A.reset_index(level=A.index.names, inplace=True)
A
F_name L_name Age Gender
0 Josh Crammer 25 M
1 John Smith 29 M
2 Mellisa Simpson 32 F
3 Ahemed Khan 26 M
4 Frank J 25 M
5 Charles Brown 26 M
6 William Gibson 26 M
现在需要做的就是添加一个 not in 条件来获取我们需要的行:
A[~((A.F_name.isin(B.F_name)) & (A.L_name.isin(B.L_name)))]
F_name L_name Age Gender
1 John Smith 29 M
3 Ahemed Khan 26 M
假设我有两个集合 'A' 和 'B',我如何在 pandas 中创建集合 C= A 减去 B。这里 A 和 B 是数据帧。 A 是一个包含名字和姓氏作为多索引的数据框。 B 有整数作为索引。名字和姓氏是 B 中的列。
我尝试通过 A['index']=A.index 将 A 的多索引转换为 A 的列,后来尝试合并 B 并且 A.But 它不起作用。
甲:
乙:
B 的列(f_Name 和 l_name)是 A 的多索引。
我想要 A 中 f_name 和 l_name 不存在于 B 中的所有行作为输出。我试过以下代码:
A['index']=A.index
my_df=pd.merge(A,B,left_on=['F_name','L_name'],right_index=True,how='left']
ans_df=A[~A.index.isin(my_df.index)]
但是 len(and_df) 与 len(A) 相同,这是不正确的。 ans_df的长度应该小于A的长度,因为B中只有f_name和l_name
使用假列的解决方案
免责声明:您可以在下面找到 "fake column" 方法的示例,该方法可能不适用于具有许多复杂类型的匹配列的大型数据帧。此外,我更喜欢使用简单的索引并将尽可能多的数据放入列而不是索引中。
那么,让我们创建两个数据集:A 将包含几个随机的恶搞之家角色,B 将包含几个恶搞之家家庭成员。希望您熟悉这部精彩的电视剧! :)
# Create a DF A with some Quahog Family guy citizens (with multiindex)
multiindexA = pd.MultiIndex.from_tuples([["Peter","Griffin"],["Glenn","Quagmire"],["Joe","Swanson"],["Cleveland","Brown"],["Brian","Griffin"],["Stewie","Griffin"],["Lois","Griffin"]],names=["Name","Surname"])
A=pd.DataFrame([40,35,38,45,8,2,35],index=multiindexA, columns=["Age"])
print A
Age
Name Surname
Peter Griffin 40
Glenn Quagmire 35
Joe Swanson 38
Cleveland Brown 45
Brian Griffin 8
Stewie Griffin 2
Lois Griffin 35
# Create a DF B with some Family guy inner family members (with simple simple index)
B = pd.DataFrame(data=[["Peter","Griffin",40],["Lois","Griffin",35],["Brian","Griffin",8],["Stewie","Griffin",2]], columns=["Name","Surname","Age"])
print B
Name Surname Age
0 Peter Griffin 40
1 Lois Griffin 35
2 Brian Griffin 8
3 Stewie Griffin 2
让我们找出不属于格里芬家族成员的恶搞之家角色。首先,我们将使用 reset_index
将数据帧规范化为相同的结构,因为这将使我们的生活更轻松:
# Reset index to move multiindex into columns in order to normalize dataframes
A = A.reset_index()
print A
Name Surname Age
0 Peter Griffin 40
1 Glenn Quagmire 35
2 Joe Swanson 38
3 Cleveland Brown 45
4 Brian Griffin 8
5 Stewie Griffin 2
6 Lois Griffin 35
由于您在两个(或更多列)上进行匹配,一个(可能是脏的和内存浪费的)解决方案可能是 通过将有趣的列组合成一个来创建假索引列具有 .apply(lambda x: ...)
功能。请记住,您必须使用 .astype(str)
.:
#Create a new dummy column by merging all matching columns into one (in both dataframes!)
A["fake_index_col"]=A[["Name","Surname","Age"]].astype(str).apply(lambda x: "".join(x),axis=1)
B["fake_index_col"]=B[["Name","Surname","Age"]].astype(str).apply(lambda x: "".join(x),axis=1)
这将向两个数据帧添加一个虚拟列,所有匹配数据将被压缩到一个字段中。
Name Surname Age fake_index_col
0 Peter Griffin 40 PeterGriffin40
1 Glenn Quagmire 35 GlennQuagmire35
2 Joe Swanson 38 JoeSwanson38
3 Cleveland Brown 45 ClevelandBrown45
4 Brian Griffin 8 BrianGriffin8
5 Stewie Griffin 2 StewieGriffin2
6 Lois Griffin 35 LoisGriffin35
这将使您可以轻松地应用 isin
函数的反函数来找到不是狮鹫的 Quahog 公民。最后删除假列 and/or 重新创建多索引以保留数据帧的初始状态。
C = A[~A["fake_index_col"].isin(B["fake_index_col"])]
del C["fake_index_col"]
print C
Name Surname Age
1 Glenn Quagmire 35
2 Joe Swanson 38
3 Cleveland Brown 45
这是数据帧 A 和 B
import pandas as pd
import numpy as np
A
Age Gender
F_name L_name
Josh Crammer 25 M
John Smith 29 M
Mellisa Simpson 32 F
Ahemed Khan 26 M
Frank J 25 M
Charles Brown 26 M
William Gibson 26 M
B
F_name L_name
0 Josh Crammer
2 Mellisa Simpson
4 Frank J
5 Charles Brown
6 William Gibson
我们可以做的是重置 A 的索引并像这样在适当的位置创建列。
A.reset_index(level=A.index.names, inplace=True)
A
F_name L_name Age Gender
0 Josh Crammer 25 M
1 John Smith 29 M
2 Mellisa Simpson 32 F
3 Ahemed Khan 26 M
4 Frank J 25 M
5 Charles Brown 26 M
6 William Gibson 26 M
现在需要做的就是添加一个 not in 条件来获取我们需要的行:
A[~((A.F_name.isin(B.F_name)) & (A.L_name.isin(B.L_name)))]
F_name L_name Age Gender
1 John Smith 29 M
3 Ahemed Khan 26 M