我想这个任务很简单,但我无法找到如何正确完成。
我有一个数据框,我必须使用最后一列才能选择一些行。所以我有以下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]
我希望你能理解这个问题。 提前谢谢!
答案 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]