Замените значение столбца Pandas другим, если какой-либо один атрибут соответствует (определите, имеют ли два столбца общий атрибут) - PullRequest
0 голосов
/ 18 сентября 2018

Предполагается пример кадра данных:

   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

или

   Chemical   Compound     Name Identifier
0   Alcohol    Ethanol   Liquor    Alcohol
1     Hooch        NaN   Liquor    Alcohol
2   Cerveza    Ethanol      NaN    Alcohol
3   Bauxite  Aluminium Gibbsite    Bauxite
4  Feldspar  Aluminium      NaN    Bauxite

Ответы [ 2 ]

0 голосов
/ 18 сентября 2018

Это скрытый вопрос о консолидации / связанных компонентах / объединении-поиске.

Если мы произвольно решим рассматривать его как проблему со связанными компонентами, мы можем представить каждое слово в вашем фрейме как узел.Строка в основном говорит, что элементы там эквивалентны или, другими словами, достижимы: между узлами есть ребра.Чтобы определить набор синонимов, нам нужно найти связанные компоненты графа.

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

, потому что, как только мы сделаем граф с ребрами (эквивалентности)

In [233]: G.edges()
Out[233]: 
[(0, 'Alcohol'),
 (0, 'Ethanol'),
 (0, 'Liquor'),
 ('Ethanol', 2),
 ('Liquor', 1),
 (1, 'Hooch'),
 (2, 'Cerveza'),
 (3, 'Bauxite'),
 (3, 'Aluminium'),
 ('Aluminium', 4),
 (4, 'Feldspar')]

мы можем попросить networkx найти группы:

In [234]: list(nx.connected_components(G))
Out[234]: 
[{0, 1, 2, 'Alcohol', 'Cerveza', 'Ethanol', 'Hooch', 'Liquor'},
 {3, 4, 'Aluminium', 'Bauxite', 'Feldspar'}]

А затем остальные просто превращают их в числа и произвольно выбирают использование первой записи Chemical в качестве имени каждогоgroup.

Мы могли бы сделать то же самое, используя функцию 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'}]

и снова у нас есть группы, которые нам нужны.

0 голосов
/ 18 сентября 2018

Чтобы определить строки, которые имеют хотя бы один соответствующий столбец:

>>> 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: Алюминий.

Однако мне не ясна ваша логика заполнения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...