Панды - группирование сообщений как разговоров путем связывания нескольких строк на основе идентификаторов из двух столбцов - PullRequest
0 голосов
/ 14 марта 2019

У меня есть некоторые данные, которые отслеживают твиты и ответы на основе source_id и response_id.Source_id может быть связан с оригинальным сообщением или ответом, который имеет свой собственный ответ.Если есть несколько ответов, то каждый ответ будет иметь source_id, и этот source_id появится в response_id соответствующего ответа.

Возьмите этот кадр данных, например:

df = pd.DataFrame({
'date': ['2018-10-02', '2018-10-03', '2018-10-03', '2018-10-03', '2018-10-03', '2018-10-03', '2018-10-03', '2018-10-03', '2018-10-03'],
'id': ['334', '335', '336', '337', '338', '340', '341', '343', '358'],
'source_id': ['830', '636', '657', '569', '152', '975', '984', '720', '524'],
'reply_id': [np.nan, '495', '636', '657', '569', '830', '152', np.nan, np.nan]
})

и его вывод:

         date   id source_id reply_id
0  2018-10-02  334       830      NaN
1  2018-10-03  335       636      495
2  2018-10-03  336       657      636
3  2018-10-03  337       569      657
4  2018-10-03  338       152      569
5  2018-10-03  340       975      830
6  2018-10-03  341       984      152
7  2018-10-03  343       720      NaN
8  2018-10-03  358       524      NaN

Каждая строка содержит данные для одного сообщения.Для сообщения есть уникальный идентификатор, будь то твит или ответ на твит.В этом примере есть два «разговора» с одним или несколькими ответами на исходное сообщение и два отдельных твита без ответов.Твиты без ответов: df.iloc[7] и df.iloc[8], оба из которых имеют NaN в response_id, а их source_ids не отображаются в response_ids других строк.В то время как df.iloc[0] имеет значение NaN в reply_id, его source_id появляется в response_id df.iloc[5].Так что это будет считаться одним разговором.

Я действительно борюсь с тем, как связать воедино серию твитов / ответов, таких как df.iloc[1], df.iloc[2], df.iloc[3], df.iloc[4]и df.iloc[6] и посчитайте все это как один разговор.И для этого конкретного разговора нет никаких данных, доступных для исходного сообщения, поэтому нет строки с source_id = 495.

Кто-нибудь имеет какие-либо идеи о том, как подойти к этому?

1 Ответ

1 голос
/ 14 марта 2019

Насколько я понимаю, это больше похоже на проблему с сетью, поэтому мы используем networkx

import networkx as nx 
G=nx.from_pandas_edgelist(df.dropna(), 'reply_id', 'source_id')
l=list(nx.connected_components(G))
newdf=pd.DataFrame(l)
newdf
Out[334]: 
     0    1     2     3     4     5
0  975  830  None  None  None  None
1  984  495   636   152   569   657 
# here you saw all the value belong to one group, they are in the same line 

Более подробно, сейчас та же группа индексов будет иметь тот же идентификатор

d=[dict.fromkeys(y,x)for x , y in enumerate(list(nx.connected_components(G)))]
d={k:v for element in d for k,v in element.items()}
ids=df.reply_id.dropna().map(d)
ids
Out[344]: 
1    1
2    1
3    1
4    1
5    0
6    1
Name: reply_id, dtype: int64
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...