Как найти предыдущее значение, отличное от другого значения в кадре данных Python - PullRequest
0 голосов
/ 09 мая 2018

Полагаю, это легко, но я не могу понять, как это сделать правильно.

У меня есть датафрейм, последний столбец которого я должен использовать, чтобы выбрать несколько строк. Итак, у меня есть следующий df:

      packet_length  src_port  dst_port comm_type
1)    280             46306.0     443.0        10
2)    105             33105.0    9999.0        00
3)    105             33105.0    9999.0        00
4)    105             33105.0    9999.0        00
5)    127              9999.0   33105.0        00
6)    127              9999.0   33105.0        00
7)    127              9999.0   33105.0        00
8)    583             45914.0     443.0        01
9)    1066              443.0   46306.0        10
10)    73             46306.0     443.0        10
11)   278             46306.0     443.0        11

Затем я хочу выполнить итерацию по столбцам последнего кадра данных, поэтому, когда я нашел значение '00', получим предыдущую строку со значением comm_type, отличным от '00' или '11', и без учета дубликаты.

То, что я до сих пор пробовал, это:

import pandas as pd
df = pd.read_csv('db.csv', error_bad_lines=False, warn_bad_lines=False)
df = df.head(n=10)


df_without_cons_dup = df.copy()

df_without_cons_dup = df_without_cons_dup.loc[df_without_cons_dup.comm_type.shift(-1) != df_without_cons_dup.comm_type]

df_without_cons_dup.reset_index(inplace=True)


df_00_01 = []
df_00_10 = []
df_11_01 = []
df_11_10 = []

tidx = 0
for indx, item in df_without_cons_dup.iterrows():
    if item.comm_type == '00':
        val = df_without_cons_dup.comm_type[indx-1]
        if val == '10':
            pkt_len = df_without_cons_dup.packet_length[indx-1]
            df_00_10.append(pkt_len)
        elif val == '01':
            pkt_len = df_without_cons_dup.packet_length[indx-1]
            df_00_01.append(pkt_len)
        else:
            continue
    elif item.comm_type == '11':
        val = df_without_cons_dup.comm_type[indx-1]
        if val == '10':
            pkt_len = df_without_cons_dup.packet_length[indx-1]
            df_11_10.append(pkt_len)
        elif val == '01':
            pkt_len = df_without_cons_dup.packet_length[indx-1]
            df_11_01.append(pkt_len)
        else:
            continue
    else:
        continue

Но проблема, которую я понял, заключается в том, что удаление дуплисов неправильно, потому что, возможно, мне не хватает информации. Кроме того, несмотря на то, что этот код работает, он не принимает во внимание тот факт, что предыдущий элемент может быть другим «00» или «11».

Пустые списки должны хранить значения, которые я ищу, поэтому для упомянутого ранее кадра данных ожидаемый результат:

df_00_01 = []
df_00_10 = [280]
df_11_01 = []
df_11_10 = [73]

Хотелось бы, чтобы вы поняли вопрос. Заранее спасибо!

1 Ответ

0 голосов
/ 09 мая 2018

Я считаю, что вам нужно:

#first filter out duplicates of `00` and `11` values, keep first value only
df1 = df[~(df['comm_type'].ne(df['comm_type'].shift()).cumsum().duplicated() & \
     df['comm_type'].isin(['00','11']))]
print (df1)
     packet_length  src_port  dst_port comm_type
1)             280   46306.0     443.0        10
2)             105   33105.0    9999.0        00
8)             583   45914.0     443.0        01
9)            1066     443.0   46306.0        10
10)             73   46306.0     443.0        10
11)            278   46306.0     443.0        11

m1 = df1['comm_type'] == '00'
m2 = df1['comm_type'] == '11'
#get positions of values to numpy array and subtract 1 for previous value
#np.clip is for 0 instead -1 if first value is 00 or 11  
pos = df.columns.get_indexer(['packet_length','comm_type'])
a00 = df1.iloc[np.clip(np.where(m1)[0] - 1, 0, len(df)), pos]
a11 = df1.iloc[np.clip(np.where(m2)[0] - 1, 0, len(df)), pos]
print (a00)
    packet_length comm_type
1)            280        10

print (a11)
     packet_length comm_type
10)             73        10

df_00_01 = a00.loc[a00['comm_type'] == '01', 'packet_length'].tolist()
df_00_10 = a00.loc[a00['comm_type'] == '10', 'packet_length'].tolist()
df_11_01 = a11.loc[a11['comm_type'] == '01', 'packet_length'].tolist()
df_11_10 = a11.loc[a11['comm_type'] == '10', 'packet_length'].tolist()

print (df_00_01)
[]
print (df_00_10)
[280]
print (df_11_01)
[]
print (df_11_10)
[73]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...