如何找到与python数据帧中的另一个值不同的先前值

时间:2018-05-09 13:50:31

标签: python pandas

我想这个任务很简单,但我无法找到如何正确完成。

我有一个数据框,我必须使用最后一列才能选择一些行。所以我有以下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 :(得分:0)

我相信你需要:

#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]