Python объединить данные взаимодействия в одну строку - PullRequest
0 голосов
/ 29 апреля 2018

У меня есть набор данных .csv с данными RFID, по которым взаимодействовали вторые люди:

tag_me - это переменная человека 1, tag_them - это имя человека, которого вы встретили в эту секунду, time_local_s - это время, когда произошло взаимодействие. Rfid начал запись в 19:00:00, поэтому первое взаимодействие было записано в 19:22:36 (19:00:00 + 1356 секунд).

tag_me,tag_them,time_local_s
0x597E5627,0x3C992634,1356
0x597E5627,0x3C992634,1360
0x597E5627,0x3C992634,1361
0x597E5627,0x3C992634,1362
0x597E5627,0x3C992634,1363
0x597E5627,0x7DA8FFB0,1364
0x597E5627,0x3C992634,1365
0x597E5627,0x3C992634,1365
0x597E5627,0x3C992634,1366
0x597E5627,0x7DA8FFB0,1366
0x597E5627,0x36570942,1366
0x597E5627,0x3C3A21AD,1369
0x597E5627,0x06497CA4,1370
0x597E5627,0x06497CA4,1372
0x597E5627,0x06497CA4,1372
0x597E5627,0x06497CA4,1374
0x597E5627,0x06497CA4,1374
0x597E5627,0x064F5882,1379

Я бы хотел сгруппировать каждое взаимодействие в одну строку, записывая время, когда взаимодействие начиналось, заканчивалось и сколько времени это заняло. поэтому я могу фильтровать по определенному порогу (два RFID видят друг друга в течение 2 секунд, конечно же, это не взаимодействие.

tag_me,tag_them,time_start,time_end,total_time
0x597E5627,0x3C992634,1356,1363,7
0x597E5627,0x7DA8FFB0,1364,1363,1
0x597E5627,0x3C992634,1365,1366,1
0x597E5627,0x7DA8FFB0,1366,1366,1
0x597E5627,0x36570942,1366,1366,1
0x597E5627,0x3C3A21AD,1369,1369.1
0x597E5627,0x06497CA4,1370,1374,4
0x597E5627,0x064F5882,1379,1379,1 

Я пробовал это до сих пор:

data = []
with open('timemerger.csv') as f:
    for line in f:
        data.append(line)

past_interactions = []
interactions = []
now = -1
new_data = []
for line in enumerate(data):
    if line["time_local_s"] > now:
        for tag_them, indices in past_interactions:
            if tag_them not in data:
                interactions.append(entry["tag_them"])

--------------- РЕДАКТИРОВАТЬ 7-5-2018 ----------

import pandas as pd
df = pd.read_csv('filter20seconden1.csv')

cols = df.columns.difference(['time_start', 'time_end'])
grps = df.time_start.sub(df.time_end.shift()).gt(20).cumsum()
gpby = df.groupby(grps)
new = gpby.agg(dict(time_start='min', 
      time_end='max')).join(gpby[cols].sum())

Ответы [ 2 ]

0 голосов
/ 29 апреля 2018

Попробуйте использовать сдвиг данных и групповую обработку, как показано ниже,

import pandas
df = pd.read_csv('timemerger.csv')
g = (df['tag_me'] != df.shift().fillna(method='bfill')['tag_me']).cumsum().
rename('group')
print(df.groupby(['tag_them','tag_me',g])['time_local_s'].agg(['min','max']).reset
_index().rename(columns={'min':'time_start','max':'time_end'}).drop('group',axis
=1))
0 голосов
/ 29 апреля 2018

Видя, как вы упомянули в своих комментариях, вы не против использовать pandas, вот одно из решений. Это немного долго, возможно, есть более эффективный способ, но я думаю, что он работает:

import pandas as pd
# Read in your csv
df = pd.read_csv('timemerger.csv')
# Create a new column with an "interaction number"
df = df.assign(interaction_num=(df.tag_them != df.tag_them.shift()).cumsum())
# Groupby the interaction number, and extract the min and max times:
gb = (df.groupby('interaction_num')
      .apply(
          lambda x: pd.Series([x['time_local_s'].min(),
                               x['time_local_s'].max()]
          ))
      .rename(columns={0:'time_start', 1:'time_end'}))
# Merge the min and max times per interaction number with your original dataframe:
df = df.merge(gb, left_on = 'interaction_num', right_index=True)
# Create a new column for length of time, groupby interaction again, and take first value:
df = (df.assign(total_time = df.time_end - df.time_start)
      .groupby('interaction_num')
      .first()
      .drop('time_local_s', axis=1))
# Finally, save your dataframe:
df.to_csv('output.csv', index=None)

Ваш новый output.csv будет выглядеть так:

tag_me,tag_them,time_start,time_end,total_time
0x597E5627,0x3C992634,1356,1363,7
0x597E5627,0x7DA8FFB0,1364,1364,0
0x597E5627,0x3C992634,1365,1366,1
0x597E5627,0x7DA8FFB0,1366,1366,0
0x597E5627,0x36570942,1366,1366,0
0x597E5627,0x3C3A21AD,1369,1369,0
0x597E5627,0x06497CA4,1370,1374,4
0x597E5627,0x064F5882,1379,1379,0

Обратите внимание, что есть нули, когда взаимодействие начиналось и заканчивалось в одну и ту же секунду, тогда как желаемый результат имел 1. Это легко изменить, используя df.replace({'total_time':{0:1}}, inplace=True) перед вашим to_csv (я сохранил его там, потому что я думаю, что в противном случае ваши данные теряют разницу между взаимодействиями с нулевой секундой и взаимодействиями с 1 секундой).

Разбивка

Первые assign() и .shift() создают столбец для отдельных взаимодействий:

       tag_me    tag_them  time_local_s  interaction_num
...
3  0x597E5627  0x3C992634          1362                1
4  0x597E5627  0x3C992634          1363                1
5  0x597E5627  0x7DA8FFB0          1364                2
6  0x597E5627  0x3C992634          1365                3
7  0x597E5627  0x3C992634          1365                3
...

Затем функция .groupby и lambda Получает время взаимодействия min и max и переименовывает его в time_start и time_end:

                 time_start  time_end
interaction_num                      
1                      1356      1363
2                      1364      1364
3                      1365      1366
4                      1366      1366
...

Затем вы объединяете результат этого groupby с исходным кадром данных, где interaction_num соответствует индексу, в результате чего:

...
3  0x597E5627  0x3C992634          1362                1        1356      1363
4  0x597E5627  0x3C992634          1363                1        1356      1363
5  0x597E5627  0x7DA8FFB0          1364                2        1364      1364
6  0x597E5627  0x3C992634          1365                3        1365      1366
7  0x597E5627  0x3C992634          1365                3        1365      1366
...

И, наконец, вы создаете столбец разницы во времени, снова используя assign и снова groupby interaction_num, и отбрасывая ненужный столбец 'time_local_s', получая ваш окончательный кадр данных.

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