#python #pandas
Вопрос:
Я боролся с изменением позиции pandas record в зависимости от конкретных условий. Что я хочу сделать, так это переместить каждую строку, имеющую значение в столбце before_id(она включает строку), в следующее индексное место другой строки, значение которой в node_id(она включает строку) совпадает с ней. И мой код не сработал так, как я ожидал. Он не вернул никаких ошибок, но вообще не сортировал их.
Хотя я немного беспокоюсь о своем объяснении …. У вас есть какая-нибудь идея, как этого добиться ?? или это невозможно сделать у Панд ??
client_data = """node_id,option,before_id
1aa,A,
8xyz,C,2aa
2aa,A,1aa
5mm,A,4bb
4bb,C,8xyz
6ccc,5mm,
7,C,6ccc
"""
df = pd.read_csv(io.StringIO(client_data), dtype='string', error_bad_lines=False)
before = pd.notnull(df['before_id'])
for ind,row in df.iterrows():
if pd.notnull(row[2]):
before_id = row[2]
before_ind = df.index[df['node_id']==before_id]
next_ind = before_ind 1
row.reindex(index=next_ind)
else:
pass
df
node_id,option,before_id
1aa,A,
8xyz,C,2aa
2aa,A,1aa
5mm,A,4bb
4bb,C,8xyz
6ccc,5mm,
7,C,6ccc
ideal output
node_id,option,before_id
1aa,A,
2aa,A,1aa
8xyz,C,2aa
4bb,C,8xyz
5mm,A,4bb
6ccc,5mm,
7,C,6ccc
Комментарии:
1. Ваш пример сложен и неоднозначен. Не могли бы вы привести минимальный пример, содержащий только уникальные цифры или отдельные буквы, чтобы прояснить вашу логику? Например, как
5
изменяется значение второго ряда2xxx
?2. Как
5
меняется значение во втором ряду2xxx
, но8
не меняется значение в третьем1aa
?3. Спасибо за комментарий , я написал это неправильно по ошибке . Я уже отредактировал df и удалил дубликаты. Все выглядит нормально ??
Ответ №1:
Похоже, вы пытаетесь решить проблему с графом поиска, ориентированным на глубину. Ниже приведено решение с использованием библиотеки графиков networkx.
import pandas as pd
import io
x = '''node_id,option,before_id
1aa,A,
8xyz,C,2aa
2aa,A,1aa
5mm,A,4bb
4bb,C,8xyz
6ccc,5mm,
7,C,6ccc'''
df = pd.read_csv(io.StringIO(x))
print("Originaln",df)
print('--------------n')
import networkx as nx
G = nx.from_pandas_edgelist(df, 'before_id', 'node_id', 'option')
sortedNodes = [n[1] for n in list(nx.dfs_edges(G))]
df.node_id = df.node_id.astype('category')
df.node_id.cat.set_categories(sortedNodes, inplace=True)
df = df.sort_values(['node_id'])
print("Node-sortedn",df)
Выход:
Original
node_id option before_id
0 1aa A NaN
1 8xyz C 2aa
2 2aa A 1aa
3 5mm A 4bb
4 4bb C 8xyz
5 6ccc 5mm NaN
6 7 C 6ccc
--------------
Node-sorted
node_id option before_id
0 1aa A NaN
2 2aa A 1aa
1 8xyz C 2aa
4 4bb C 8xyz
3 5mm A 4bb
5 6ccc 5mm NaN
6 7 C 6ccc
Комментарии:
1. Кроме того, python 3.9 имеет встроенную библиотеку graphlib, которая может предоставлять те же возможности, что и networkx. Вы можете проверить это по адресу: docs.python.org/3/library/graphlib.html
2. Огромное спасибо. Ваш код работает без каких-либо ошибок, но он возвращает результаты, отличные от ваших . Может быть , как вы сказали, это зависит от моей версии Python, 3.8. Я проверю документы.