Python 如果任何单个属性匹配,则用另一个替换熊猫的列值(确定两列是否具有公共属性)

Python 如果任何单个属性匹配,则用另一个替换熊猫的列值(确定两列是否具有公共属性),python,pandas,Python,Pandas,假设一个示例数据帧: Chemical Compound Name 0 Alcohol Ethanol Liquor 1 Hooch NaN Liquor 2 Cerveza Ethanol NaN 3 Bauxite Aluminium Gibbsite 4 Feldspar Aluminium NaN 替换或识别两行是否相同的有效方法是什么?(如果任何属性(列)匹配,则假设两行相同,但不一定全

假设一个示例数据帧:

   Chemical   Compound     Name
0   Alcohol    Ethanol   Liquor
1     Hooch        NaN   Liquor
2   Cerveza    Ethanol      NaN
3   Bauxite  Aluminium Gibbsite
4  Feldspar  Aluminium      NaN
替换或识别两行是否相同的有效方法是什么?(如果任何属性(列)匹配,则假设两行相同,但不一定全部匹配)

结果可能是:

   Chemical   Compound     Name
0   Alcohol    Ethanol   Liquor
1   Alcohol        NaN   Liquor
2   Alcohol    Ethanol      NaN
3   Bauxite  Aluminium Gibbsite
4   Bauxite  Aluminium      NaN
或:


要标识至少有一个匹配列的行,请执行以下操作:

>>> df.apply(lambda x: x.dropna().duplicated()).any(axis=1)
0    False
1     True
2     True
3    False
4     True
dtype: bool
在上面,第1、2和4行是“重复的”。第1行:白酒,第2行:乙醇,第4行:铝


但是,我不清楚您的填充逻辑。

要标识至少有一个匹配列的行,请执行以下操作:

>>> df.apply(lambda x: x.dropna().duplicated()).any(axis=1)
0    False
1     True
2     True
3    False
4     True
dtype: bool
在上面,第1、2和4行是“重复的”。第1行:白酒,第2行:乙醇,第4行:铝


但是,我不清楚您的填充逻辑。

这是一个伪装的集合整合/连接组件/联合查找问题

如果我们任意决定将其视为一个连接组件问题,我们可以将帧中的每个单词想象为一个节点。一行基本上表示那里的元素是等价的,或者换句话说,是可到达的:节点之间有边。要确定同义词集,我们需要找到图中的连通分量

import networkx as nx
G = nx.from_pandas_dataframe(df.stack().reset_index(), source='level_0', target=0)
codes = {v: i for i, vv in enumerate(nx.connected_components(G)) for v in vv}
df["Identifier"] = df["Chemical"].groupby(df["Chemical"].replace(codes)).transform("first")
给我

In [229]: df
Out[229]: 
   Chemical   Compound    Name Identifier
0   Alcohol    Ethanol  Liquor    Alcohol
1     Hooch        NaN  Liquor    Alcohol
2   Cerveza    Ethanol     NaN    Alcohol
3   Bauxite  Aluminium     NaN    Bauxite
4  Feldspar  Aluminium     NaN    Bauxite
因为一旦我们用边(等价物)绘制了图

我们可以要求networkx查找以下组:

In [234]: list(nx.connected_components(G))
Out[234]: 
[{0, 1, 2, 'Alcohol', 'Cerveza', 'Ethanol', 'Hooch', 'Liquor'},
 {3, 4, 'Aluminium', 'Bauxite', 'Feldspar'}]
然后剩下的就是把这些转化成数字,任意选择第一个化学条目作为每个组的名称

我们可以通过使用scipy的scipy.sparse.csgraph.connected_components函数来做完全相同的事情,只需稍加设置,或者简单地使用现成的集合合并算法来查找组。例如,使用集合合并算法,我们可以

In [240]: consolidate([set(row.dropna()) for _, row in df.iterrows()])
Out[240]: 
[{'Alcohol', 'Cerveza', 'Ethanol', 'Hooch', 'Liquor'},
 {'Aluminium', 'Bauxite', 'Feldspar'}]

我们又一次拥有了我们所需要的团队。

这是一套整合/连接组件/联合查找问题的伪装

如果我们任意决定将其视为一个连接组件问题,我们可以将帧中的每个单词想象为一个节点。一行基本上表示那里的元素是等价的,或者换句话说,是可到达的:节点之间有边。要确定同义词集,我们需要找到图中的连通分量

import networkx as nx
G = nx.from_pandas_dataframe(df.stack().reset_index(), source='level_0', target=0)
codes = {v: i for i, vv in enumerate(nx.connected_components(G)) for v in vv}
df["Identifier"] = df["Chemical"].groupby(df["Chemical"].replace(codes)).transform("first")
给我

In [229]: df
Out[229]: 
   Chemical   Compound    Name Identifier
0   Alcohol    Ethanol  Liquor    Alcohol
1     Hooch        NaN  Liquor    Alcohol
2   Cerveza    Ethanol     NaN    Alcohol
3   Bauxite  Aluminium     NaN    Bauxite
4  Feldspar  Aluminium     NaN    Bauxite
因为一旦我们用边(等价物)绘制了图

我们可以要求networkx查找以下组:

In [234]: list(nx.connected_components(G))
Out[234]: 
[{0, 1, 2, 'Alcohol', 'Cerveza', 'Ethanol', 'Hooch', 'Liquor'},
 {3, 4, 'Aluminium', 'Bauxite', 'Feldspar'}]
然后剩下的就是把这些转化成数字,任意选择第一个化学条目作为每个组的名称

我们可以通过使用scipy的scipy.sparse.csgraph.connected_components函数来做完全相同的事情,只需稍加设置,或者简单地使用现成的集合合并算法来查找组。例如,使用集合合并算法,我们可以

In [240]: consolidate([set(row.dropna()) for _, row in df.iterrows()])
Out[240]: 
[{'Alcohol', 'Cerveza', 'Ethanol', 'Hooch', 'Liquor'},
 {'Aluminium', 'Bauxite', 'Feldspar'}]

我们又一次得到了所需的组。

df.duplicated()
?“如果任何属性(列)匹配”,那么这些行完全相同是什么意思?示例?@Alexander在上述数据框中的示例:酒精、Hooch和Cerveza“相同”(酒精和Hooch有普通白酒,铝土矿和长石有普通铝),您有networkx或scipy可用吗?虽然我们可以在纯Python/pandas中实现这一点,但使用现有函数更容易。我认为networkx是解决这类问题的好方法。我对networkx并不熟悉。我要读一读。谢谢
df.duplicated()
?“如果任何属性(列)匹配”,那么这些行完全相同是什么意思?示例?@Alexander在上述数据框中的示例:酒精、Hooch和Cerveza“相同”(酒精和Hooch有普通白酒,铝土矿和长石有普通铝),您有networkx或scipy可用吗?虽然我们可以在纯Python/pandas中实现这一点,但使用现有函数更容易。我认为networkx是解决这类问题的好方法。我对networkx并不熟悉。我要读一读。谢谢