如何在 pandas Dataframe KeyError: False 中索引出数字的值

Posted

技术标签:

【中文标题】如何在 pandas Dataframe KeyError: False 中索引出数字的值【英文标题】:How to index out value of number in pandas Dataframe KeyError: False 【发布时间】:2020-09-25 08:50:21 【问题描述】:

所以我试图在过滤后索引一个值以将其附加到列表中。到目前为止,这里是代码:

import pandas as pd
import numpy as np
arr_1 = np.array([7, 1, 6, 9, 2, 4])
arr_2 = np.array([5, 8, 9, 10, 2, 3])
arr_3 = np.array([1, 9, 3, 4, 5, 1])

dict_of_arrs = 
    'arr' : [arr_1, arr_2, arr_3]

df = pd.DataFrame(dict_of_arrs)

true_list = []
false_list = []
filt = df.arr.apply(lambda x: np.diff(x)>0)
for i in filt:
    for n in i:
        if n==True:
            true_list.append(df.arr[n])
        else:
            false_list.append(df.arr[n])

虽然我得到了错误:

KeyError: False

我也通过df.arr[i][n] 进行索引,但正如预期的那样,这给了我错误:

IndexError: Boolean index has wrong length: 5 instead of 3

我想做的是过滤掉我已经拥有的 True 或 False,然后我想将所有 True 值的原始编号附加到 true_list 和 False 相同。因此,当我执行print(true_list) 时,输出是一个列表列表,每个列表只有 filt==True 的值,对于 false_list 也是如此。谢谢。

编辑: 预期输出应类似于:

print(true_list)

那么输出是:

[ 6, 9, 4]
[ 8, 9, 10, 3]
[ 9, 4, 5]

因为在每个列表中,如果后面的值大于最后一个值,则 filt 正在寻找。因此,那些为真的,将它们的 int 值添加到 true_list 中。对于 false_list,它看起来像:

[ 1, 2]
[2]
[3, 1]

谢谢

【问题讨论】:

你想在这里做什么,前段时间也有人问过同样的问题。你的预期输出是什么? 我认为,如果您展示您的预期输出,将会有很长的路要走。有更好的方法来做到这一点。 np.diff 为您提供 5 个 bool 值的列表,而您的原始数组有 6 个 ints。您打算如何匹配这些索引?目前还不清楚您需要什么。 那么请再次阅读我的评论。您打算如何将 6 个ints 匹配到 5 个bools?同样,如果您可以edit 您的问题来显示您的预期最终结果,这将有所帮助。我们想帮助你,但你必须帮助我们帮助你。 请用列表的格式、对象的形状等修改您的问题。 【参考方案1】:

这与@Scott Boston's answer 相同,但不使用groupbyexplode

使用np.diff 和布尔索引。

import numpy as np

df.arr.map(lambda x:np.array(x)[1:][np.diff(x)>=0])
0        [6, 9, 4]
1    [8, 9, 10, 3]
2        [9, 4, 5]
Name: arr, dtype: object

df.arr.map(lambda x:np.array(x)[1:][np.diff(x)<0])
0    [1, 2]
1       [2]
2    [3, 1]
Name: arr, dtype: object

timeit 结果:

In [63]: %%timeit
    ...: dfe = df['arr'].explode()
    ...: grp = dfe.groupby(level=0).diff()
    ...: df_g = dfe[grp >= 0]
    ...: df_increasing = df_g.groupby(level=0).agg(list)
    ...: 
    ...: df_l = dfe[grp < 0]
    ...: df_decreasing = df_l.groupby(level=0).agg(list)
    ...:
    ...:
7.16 ms ± 565 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [65]: %%timeit
    ...: df_x = df.arr.map(lambda x:np.array(x)[1:][np.diff(x)>=0])
    ...: df_y =df.arr.map(lambda x:np.array(x)[1:][np.diff(x)<0])
    ...:
    ...:
384 µs ± 5.37 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

【讨论】:

【参考方案2】:

让我们看看这是否有帮助:

dfe = df['arr'].explode()
grp = dfe.groupby(level=0).diff()
df_g = dfe[grp >= 0]
df_increasing = df_g.groupby(level=0).agg(list)

df_l = dfe[grp < 0]
df_decreasing = df_l.groupby(level=0).agg(list)

print(df_increasing)

# 0        [6, 9, 4]
# 1    [8, 9, 10, 3]
# 2        [9, 4, 5]
# Name: arr, dtype: object

print(df_decreasing)

# 0    [1, 2]
# 1       [2]
# 2    [3, 1]
# Name: arr, dtype: object

【讨论】:

很好,我一直坚持只使用gt,并没有想到只使用lt 来过滤掉误报。第一个条件应该是&gt; 0 虽然基于要求:) df_increasing = dfe.groupby(level=0).agg(lambda x:x[x.diff().ge(0)].tolist()) 减少了groupby 的重复使用。不错的答案+1

以上是关于如何在 pandas Dataframe KeyError: False 中索引出数字的值的主要内容,如果未能解决你的问题,请参考以下文章

Pandas:如何将 cProfile 输出存储在 pandas DataFrame 中?

如何在 jupyter 中像 pandas Dataframe 一样打印 Pyspark Dataframe

如何在 Pandas 中将 DataFrame 的行迭代为 Series?

如何在 pandas.DataFrame.plot() 中为标题设置字体大小?

python: pandas.DataFrame,如何避免keyerror?

如何在 Pandas 中将两个 DataFrame 堆叠在一起?