在数据帧上循环并应用条件的正确方法是什么?

2024-09-30 02:36:37 发布

您现在位置:Python中文网/ 问答频道 /正文

我尝试循环浏览字典列表,将一个值与数据帧中的一对列进行比较,并在特定条件下向第三列添加一个值。你知道吗

我的词典列表如下所示:

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\u number”值并将其与dataframe行中的“start”和“end”列进行比较。如果页码在一行中这两个值的范围内,我想在该行的“note\u 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

谢谢你的帮助!你知道吗


Tags: idnumber字典typecountpagelocationcontent
3条回答

您不需要迭代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名称。你知道吗

我会用^{}来做这个:

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

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 

下面是一种使用^{}的方法:

m=pd.DataFrame(dict_list)
s = pd.IntervalIndex.from_arrays(df.start,df.end, 'both')
#output-> IntervalIndex([[1, 100], [101, 200], [201, 300]],
          #closed='both',
          #dtype='interval[int64]')
n=m.set_index(s).loc[m['page_number']].groupby(level=0)['page_number'].count()
n.index=pd.MultiIndex.from_arrays([n.index])

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()get counts,转换为Multiindex并将其赋值。你知道吗

相关问题 更多 >

    热门问题