假设我有一个这样的数组:
import numpy as np
base_array = np.array([-13, -9, -11, -3, -3, -4, 2, 2,
2, 5, 7, 7, 8, 7, 12, 11])
Run Code Online (Sandbox Code Playgroud)
假设我想知道:"有多少元素base_array大于4?" 这可以通过利用广播来完成:
np.sum(4 < base_array)
Run Code Online (Sandbox Code Playgroud)
答案是这样的7.现在,假设不是比较单个值,而是想在数组上执行此操作.换句话说,每个值c的comparison_array,发现的许多元素如何base_array都大于c.如果我以天真的方式这样做,它显然会失败,因为它不知道如何正确地广播它:
comparison_array = np.arange(-13, 13)
comparison_result = np.sum(comparison_array < base_array)
Run Code Online (Sandbox Code Playgroud)
输出:
Traceback (most recent call last):
File "<pyshell#87>", line 1, in <module>
np.sum(comparison_array < base_array)
ValueError: operands could not be broadcast together with shapes (26,) (16,)
Run Code Online (Sandbox Code Playgroud)
如果我能以某种方式comparison_array将广播的每个元素都变成base_array …
在Python 3.7中,这些新的“数据类”容器基本上类似于可变的namedtuple。假设我制作了一个要代表一个人的数据类。我可以通过如下__post_init__()函数添加输入验证:
@dataclass
class Person:
name: str
age: float
def __post_init__(self):
if type(self.name) is not str:
raise TypeError("Field 'name' must be of type 'str'.")
self.age = float(self.age)
if self.age < 0:
raise ValueError("Field 'age' cannot be negative.")
Run Code Online (Sandbox Code Playgroud)
这样可以通过以下方式提供良好的输入:
someone = Person(name="John Doe", age=30)
print(someone)
Person(name='John Doe', age=30.0)
Run Code Online (Sandbox Code Playgroud)
尽管所有这些错误的输入都会引发错误:
someone = Person(name=["John Doe"], age=30)
someone = Person(name="John Doe", age="thirty")
someone = Person(name="John Doe", age=-30)
Run Code Online (Sandbox Code Playgroud)
但是,由于数据类是可变的,所以我可以这样做:
someone = Person(name="John Doe", age=30)
someone.age = -30
print(someone)
Person(name='John Doe', age=-30)
Run Code Online (Sandbox Code Playgroud)
从而绕过输入验证。
因此, …
这不是问题的重复,例如Row-wise iteration like apply with purrr
我了解如何使用pmap()对数据框进行逐行操作:
library(tidyverse)
df1 = tribble(~col_1, ~col_2, ~col_3,
1, 5, 12,
9, 3, 3,
6, 10, 7)
foo = function(col_1, col_2, col_3) {
mean(c(col_1, col_2, col_3))
}
df1 %>% pmap_dbl(foo)
Run Code Online (Sandbox Code Playgroud)
foo这给出了应用于每一行的函数:
[1] 6.000000 5.000000 7.666667
Run Code Online (Sandbox Code Playgroud)
但是,当我有多个列时,这会变得非常笨拙,因为我必须显式地将它们全部传递。如果我说,我的数据框中有 8 列df2,并且我想应用一个bar可能涉及其中每一列的函数,该怎么办?
set.seed(12345)
df2 = rnorm(n=24) %>% matrix(nrow=3) %>% as_tibble() %>%
setNames(c("col_1", "col_2", "col_3", "col_4", "col_5", "col_6", "col_7", "col_8"))
bar = function(col_1, col_2, col_3, col_4, col_5, col_6, col_7, col_8) {
# …Run Code Online (Sandbox Code Playgroud) [编辑:这个问题不是这个问题的重复;我问的是语言设计的问题,即为什么它首先是这样的。我对它的行为方式并不感到困惑,我对为什么首先决定这种行为感到困惑。]
在Python(以及其他一些语言,例如Lua)中,布尔运算符and和or并不像人们所期望的那样返回布尔值True,False而是:
x or y:如果x为假,则y,否则xx and y如果x为 false,则x,否则y很容易看出,在x和y是布尔值的特殊情况下,其行为符合预期。
我的问题是,以这种方式进行概括的实际理由是什么?我知道你可以用它来实现以下技巧:
foo = x or None
Run Code Online (Sandbox Code Playgroud)
或者 DIY 三元运算符,例如:
foo = x and y or z
Run Code Online (Sandbox Code Playgroud)
但我觉得这些都不足以为这种令人惊讶的行为提供充分的理由。每当我看到非布尔返回值被依赖于其实际值(而不是在 if 语句或其他东西中,无论哪种方式都无关紧要),我总是必须仔细检查我对它的理解,因为我总是忘记它是如何工作的,我需要再次查找它。我通常更喜欢以更详细的方式编写。是否有一个根本原因为什么它应该以这种方式工作,或者它真的只是为了技巧?