遍历熊猫数据框并应用条件的正确方法是什么?

时间:2019-11-02 13:26:10

标签: python pandas

我试图遍历字典列表,将值与Pandas数据框中的一对列进行比较,并在特定条件下将值添加至第三列。

我的字典列表如下:

dict_list = [{'type': 'highlight', 'id': 0, 'page_number': 4, 'location_number': 40, 'content': 'Foo'}, {'type': 'highlight', 'id': 1, 'page_number': 12, 'location_number': 96, 'content': 'Bar'}, {'type': 'highlight', 'id': 2, 'page_number': 128, 'location_number': 898, 'content': 'Some stuff'}]

我的数据框如下:

    start    end  note_count
1       1    100           0
2     101    200           0
3     201    300           0

对于每个字典,我想提取“ page_number”值并将其与数据帧行中的“ start”和“ end”列进行比较。如果page_number在一行中这两个值的范围内,我想对该行的“ note_count”列进行+1。这是我当前的代码:

for dict in dict_list:
    page_number = dict['page_number']
    for index, row in ventile_frame.iterrows():
        ventile_frame["note_count"][(ventile_frame["start"] <= page_number) & (ventile_frame["end"] >= page_number)] += 1
print (ventile_frame)

我希望看到这样的结果。

    start    end  note_count
1       1    100           2
2     101    200           1
3     201    300           0

相反,我看到了。

    start    end  note_count
1       1    100           9
2     101    200           0
3     201    300           0

感谢您的帮助!

3 个答案:

答案 0 :(得分:1)

您不需要迭代ventile_frame的行-这就是它的美!

(ventile_frame["start"] <= page_number) & (ventile_frame["end"] >= page_number)将产生一个布尔掩码,指示page_number是否在每一行的范围内。尝试使用page_number的固定值来了解发生了什么:

print((ventile_frame["start"] <= 4) & (ventile_frame["end"] >= 4))

最重要的是,您只需要对字典进行迭代:

for single_dict in dict_list:
    page_number = single_dict['page_number']
    ventile_frame["note_count"][(ventile_frame["start"] <= page_number) & (ventile_frame["end"] >= page_number)] += 1
print (ventile_frame)

请注意,在上面的代码中,我用dict替换了single_dict,最好避免掩盖内置的python名称。

答案 1 :(得分:1)

这是使用IntervalIndex的一种方式:

final=df.set_index(['start','end']).assign(new_note_count=n).reset_index()
final['new_note_count']=final['new_note_count'].fillna(0)

   start  end  note_count  new_note_count
0      1  100           0             2.0
1    101  200           0             1.0
2    201  300           0             0.0

输出:

m

详细信息: 将索引作为间隔之后,将.loc[]page_number的索引设置为print(m.set_index(s).loc[m['page_number']])

                 type  id  page_number  location_number content
[1, 100]    highlight   0            4               40     Foo
[1, 100]    highlight   0            4               40     Foo
[101, 200]  highlight   1           12               96     Bar

groupby()

然后使用{{1}}获取计数,转换为Multiindex并将其分配回来。

答案 2 :(得分:1)

我会用DataFrame.apply来做到这一点:

首先使用字典中包含的页数创建一个系列:

page_serie=pd.Series([dict_t['page_number'] for dict_t in dict_list])
print(page_serie)

0      4
1     12
2    128
dtype: int64

然后, 对于数据框的每一行,您确定该序列的值是否在'start''end'之间以及总和

df['note_count']=df.apply(lambda x: page_serie.between(x['start'],x['end']),axis=1).sum(axis=1)
print(df)

   start  end  note_count 
1      1  100           2 
2    101  200           1 
3    201  300           0