Python: эмулируйте индексное совпадение Excel с информацией в 2 столбцах df1, чтобы использовать ее для поиска позиции в df2. - PullRequest
1 голос
/ 13 июня 2019

Помимо прочего, я пытаюсь обрабатывать большие наборы данных, поэтому я перешел с Excel на Python.Мне удалось решить большинство проблем, однако, для моих явно плохих навыков в Google мне кажется сложным следующее:

Доступные данные: у меня есть pandas dataframe1 с 500 тыс. Строк.Каждая строка содержит метку времени, номер машины и индикатор, если он активен или нет.У меня есть другой pandas dataframe2 с ~ 30 миллионами строк (одна в секунду в году) и 60 столбцами (по 1 на каждую машину).

Цель: я хотел бы заполнить пустую матрицу df2, посмотрев накаждая строка в df1.В df1 я хочу использовать информацию о метке времени, чтобы найти соответствующую строку в df2, а в df1 я хочу использовать номер машины, чтобы найти соответствующий столбец в df2, а затем вставить значение в df2

import pandas as pd

df_1 = pd.DataFrame({'timestamp':[1, 1, 4, 5],
                 'machine_number':[123, 789, 789, 123],
                 'active_inactive':[1, 0, 1, 0]})    
df_2 = pd.DataFrame({'time':[1, 2, 3, 4, 5],
                 '123':['', '', '', '', ''],
                 '789':['', '', '', '', '']})

После эмуляции совпадения индекса я стремлюсь к следующему результату

df_3 = pd.DataFrame({'time':[1, 2, 3, 4, 5],
                 '123':[1, '', '', '', 0],
                 '789':[0, '', '', 1, '']})

В конце концов я хочу заполнить пустые значения последним активным / неактивным индикатором доПоявляется новый индикатор:

df_4 = pd.DataFrame({'time':[1, 2, 3, 4, 5],
                 '123':[1, 1, 1, 1, 0],
                 '789':[0, 0, 0, 1, 1]})

Но, возможно, это проблема другого дня, который я могу попытаться решить самостоятельно.

Заранее спасибо за любыеполезная информация

Бест Свен

1 Ответ

0 голосов
/ 17 июня 2019

Добро пожаловать на SO. Так что этот вопрос на самом деле немного сложнее, чем может показаться. Первое, что нужно понять, это то, что pandas лучше всего работает с «опрятными» данными (https://en.wikipedia.org/wiki/Tidy_data). Где Excel отлично подходит для ввода данных, он не оптимизирован для анализа (как вы выяснили). Вы узнаете больше о это потому, что вы больше разбираетесь в кодировании с фреймами данных, а пока просто понимаете, что для правильной работы все должно быть в разных форматах.

Итак, сначала вам нужно перевести ваш второй файл данных из широкого в длинный формат (вам нужно привести его в порядок):

df_1 = pd.DataFrame({'timestamp':[1, 1, 4, 5],
                 'machine_number':[123, 789, 789, 123],
                 'active_inactive':[1, 0, 1, 0]})

df_2 = pd.DataFrame({'timestamp':[1, 2, 3, 4, 5], # note that I changed this name to 'timestamp' so
                                                  # it's the same in both dataframe
                 '123':['', '', '', '', ''],
                 '789':['', '', '', '', '']})

(df_2_melted = pd.melt(df_2, id_vars=['timestamp'], 
                             value_vars=['123', '789'], 
                             var_name='machine_number')
                 .drop(columns='value'))

df_2_melted['machine_number'] = df_2_melted['machine_number'].astype('int64')
# I had to change this column to 'int64' because the next operation won't work unless the
# columns are the same type

Вот тебе вот что:

    timestamp   machine_number
0   1           123
1   2           123
2   3           123
3   4           123
4   5           123
5   1           789
6   2           789
7   3           789
8   4           789
9   5           789

Затем вы можете «объединить» столбцы вместе. Это похоже на операцию соединения из sql или и index_match / vlookup в excel:

merged = pd.merge(df_2_melted, df_1, how='left', on=['timestamp', 'machine_number'])

merged

    timestamp   machine_number  active_inactive
0   1           123             1.0
1   2           123             NaN
2   3           123             NaN
3   4           123             NaN
4   5           123             0.0
5   1           789             0.0
6   2           789             NaN
7   3           789             NaN
8   4           789             1.0
9   5           789             NaN

Затем, если вы хотите вернуть его в тот же формат, что и в исходном кадре данных, вам нужно pivot вернуть его обратно (как следует из названия, это похоже на сводную таблицу из excel):

merged.pivot(index='timestamp', columns='machine_number', values='active_inactive').reset_index(drop=True)

machine_number  123     789
0               1.0     0.0
1               NaN     NaN
2               NaN     NaN
3               NaN     1.0
4               0.0     NaN

Тем не менее, вы захотите сохранить все в чистом формате для анализа, поэтому я бы предложил использовать сводку только в том случае, если вы захотите в конце концов выписать его в виде электронной таблицы, чтобы дать кому-то еще.

...