【问题标题】:Avoiding 'x' is not defined error while iterating over a DataFrame迭代 DataFrame 时避免“x”未定义错误
【发布时间】:2019-01-17 15:15:00
【问题描述】:

我找到了解决问题的方法,但我确信有更好的方法。我正在尝试遍历 DataFrame,如果迭代中的每个索引距离下一个索引

      v  
1    .15  
2    .31   
3    .64   
4    .15  
7    .62   
11   .12   
15   .39   
18   .54   
19   .84 

那么结果就是

{1:4, 18:2}

为此,我使用了以下代码:

f_dict = defaultdict(int)
for id1, id2 in zip(df.iterrows(),df_test[1:].iterrows()):        
    if id2[0] - id1[0] < 2:
        f_dict[x] += 1
    else:
        x = id1[0]

但是,当运行它时,正如预期的那样,我得到 NameError: name 'x' is not defined。因此,通过在迭代之前给 x 一个 DataFrame 的第一个索引值的值,它似乎解决了问题,但以一种感觉不对的方式。

f_dict = defaultdict(int)
x = df_test.index[0]
for id1, id2 in zip(df_test.iterrows(),df_test[1:].iterrows()):        
    if id2[0] - id1[0] < 2:
        f_dict[x] += 1
    else:
        x = id1[0]

此代码生成字典 -

 {1:3, 18:1}

而不是

 {1:4, 18:2}

因此,我遍历新的 dict 以将每个值加 1:

for key in f_dict:
    f_dict[key] += 1

终于找到了我想要的东西。对于我解决这个问题的不当方式,我深表歉意,因为我对 python 和一般编程仍然相当陌生。有没有更好的方法来解决这个问题,以避免在迭代之前设置 x 的值?以及不必再循环新的字典并将每个值增加1?非常感谢!

【问题讨论】:

    标签: python dictionary dataframe


    【解决方案1】:

    这听起来很对。我不确定您为什么期望{1:4, 18:2},因为您实际上是在比较(1, 2), (2, 3), (3,4)... 的值,您可以看到它只有1 到4 之间的3 个计数。同样在您的示例中,您最终会得到{1:3, 15:1},因为@ 987654324@ 不会在上次迭代中更新。

    解决此问题的一种方法是:

    1. 默认字典以1 开头,因为每次计数时,值的数量至少为2,因此f_dict[x] += 1 始终至少为2。
    2. 将 else 子句更改为 x = df2[0],以便它使用下一个索引作为起点。

    因此,变化将是这样的:

    f_dict = defaultdict(lambda: int(1))
    x = df_test.index[0]
    for id1, id2 in zip(df_test.iterrows(),df_test[1:].iterrows()):        
        if id2[0] - id1[0] < 2:
            f_dict[x] += 1
        else:
            x = id2[0]
    
    f_dict
    # {1:4, 18:2}
    

    我觉得可能有比iterrows() 更好的方法来做到这一点,但它现在正在逃避我。

    【讨论】:

    • 非常感谢!我尝试了 f_dict = defaultdict(1) 显然没有用,但是使用 lambda 表达式来完成它更有意义。非常感谢。
    猜你喜欢
    • 1970-01-01
    • 2021-01-17
    • 2016-03-12
    • 1970-01-01
    • 2010-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-18
    相关资源
    最近更新 更多