过滤数组时的Python语言构造



我可以在SO中看到许多关于如何过滤数组的问题(通常使用pandas或numpy)。示例非常简单:

df = pd.DataFrame({ 'val': [1, 2, 3, 4, 5, 6, 7] })
a = df[df.val > 3]

直觉上我理解df[df.val > 3]语句。但从语法的角度来看,这让我很困惑。在其他语言中,我希望使用lambda函数而不是df.val > 3

问题是:为什么这种风格是可能的,到底发生了什么?

更新1:

在其他语言中,我看到了下面的语法:
df.filter(row => row.val > 3)

我明白这里发生了什么:对于每次迭代,lambda函数被调用row作为参数并返回一个布尔值。但是这里df.val > 3对我来说没有意义,因为df.val看起来像column

此外,我可以编写df[df > 3],它将被编译并执行成功。这让我很抓狂,因为我不明白如何将DataFrame对象与数字进行比较。

创建一个数组和数据框:

In [104]: arr = np.arange(1,8); df = pd.DataFrame({'val':arr})
In [105]: arr
Out[105]: array([1, 2, 3, 4, 5, 6, 7])
In [106]: df
Out[106]: 
val
0    1
1    2
2    3
3    4
4    5
5    6
6    7

numpy数组具有对整个数组进行操作的方法和操作符。例如,可以将数组乘以一个标量,或向所有元素添加一个标量。或者在这种情况下,将每个元素与标量进行比较。这些都是由类(numpy.ndarray)实现的,而不是由Python语法实现的。

In [107]: arr>3
Out[107]: array([False, False, False,  True,  True,  True,  True])

pandas同样实现了这些方法(或者在底层数组上使用numpy方法)。选择框架的列,使用' df['val']或:

In [108]: df.val
Out[108]: 
0    1
1    2
2    3
3    4
4    5
5    6
6    7
Name: val, dtype: int32

这是熊猫系列(显示略有不同)。

可以与标量进行比较,如数组:

In [110]: df.val>3
Out[110]: 
0    False
1    False
2    False
3     True
4     True
5     True
6     True
Name: val, dtype: bool

和布尔数组可以用来索引框架:

In [111]: df[arr>3]
Out[111]: 
val
3    4
4    5
5    6
6    7

布尔级数也适用:

In [112]: df[df.val>3]
Out[112]: 
val
3    4
4    5
5    6
6    7

布尔数组索引的工作方式相同:

In [113]: arr[arr>3]
Out[113]: array([4, 5, 6, 7])

这里我使用索引来获取值;设置值是类似的。

最新更新