社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
私信  •  关注

cs95

cs95 最近创建的主题
cs95 最近回复了
5 年前
回复了 cs95 创建的主题 » 在python中,与(and,&,or,|)等价的是什么?

太长,读不下去了 熊猫中的逻辑运算符是 & , | ~ ,和括号 (...) 这很重要!

蟒蛇的 and , or not 逻辑运算符设计用于处理标量。所以Pandas必须做得更好,重写位运算符以实现 矢量化 此功能的(元素)版本。

下面是python中的( exp1 exp2 是计算为布尔结果的表达式)。。。

exp1 and exp2              # Logical AND
exp1 or exp2               # Logical OR
not exp1                   # Logical NOT

...将转化为。。。

exp1 & exp2                # Element-wise logical AND
exp1 | exp2                # Element-wise logical OR
~exp1                      # Element-wise logical NOT

为了熊猫。

如果在执行逻辑运算的过程中 ValueError ,则需要使用括号进行分组:

(exp1) op (exp2)

例如

(df['col1'] == x) & (df['col2'] == y) 

等等


Boolean Indexing :常见的操作是通过逻辑条件计算布尔掩码以过滤数据。熊猫提供 操作员: & 对于逻辑和逻辑, | 用于逻辑OR,以及 ~ 当然不是。

考虑以下设置:

np.random.seed(0)
df = pd.DataFrame(np.random.choice(10, (5, 3)), columns=list('ABC'))
df

   A  B  C
0  5  0  3
1  3  7  9
2  3  5  2
3  4  7  6
4  8  8  1

逻辑与

对于 df 上面,假设您希望返回A<5和B>5.这是通过分别计算每个条件的掩码,并对它们进行求和来实现的。

按位重载 & 操作人员
在继续之前,请注意这些文件的特别摘录,其中

另一种常见的操作是使用布尔向量来过滤 数据运营商包括: | 对于 , & 对于 ~ 对于 . 这些 ,因为默认情况下Python将 计算表达式,例如 df.A > 2 & df.B < 3 df.A > (2 & df.B) < 3 ,而所需的评估顺序为 (df.A > 2) & (df.B < 3) .

因此,考虑到这一点,元素逻辑AND可以通过位运算符实现 & :

df['A'] < 5

0    False
1     True
2     True
3     True
4    False
Name: A, dtype: bool

df['B'] > 5

0    False
1     True
2    False
3     True
4     True
Name: B, dtype: bool

(df['A'] < 5) & (df['B'] > 5)

0    False
1     True
2    False
3     True
4    False
dtype: bool

接下来的过滤步骤很简单,

df[(df['A'] < 5) & (df['B'] > 5)]

   A  B  C
1  3  7  9
3  4  7  6

括号用于覆盖按位运算符的默认优先顺序,按位运算符的优先级高于条件运算符 < > .参见 Operator Precedence 在python文档中。

如果不使用括号,则表达式的计算结果不正确。例如,如果您不小心尝试了以下操作:

df['A'] < 5 & df['B'] > 5

它被解析为

df['A'] < (5 & df['B']) > 5

这就变成了,

df['A'] < something_you_dont_want > 5

这就变成了(参见上的python文档) chained operator comparison ),

(df['A'] < something_you_dont_want) and (something_you_dont_want > 5)

这就变成了,

# Both operands are Series...
something_else_you_dont_want1 and something_else_you_dont_want2

哪个扔

ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

所以,不要犯那个错误! 1.

避免括号分组
解决方法其实很简单。对于数据帧,大多数操作符都有相应的绑定方法。如果单个掩码是使用函数而不是条件运算符构建的,则不再需要按参数分组来指定求值顺序:

df['A'].lt(5)

0     True
1     True
2     True
3     True
4    False
Name: A, dtype: bool

df['B'].gt(5)

0    False
1     True
2    False
3     True
4     True
Name: B, dtype: bool

df['A'].lt(5) & df['B'].gt(5)

0    False
1     True
2    False
3     True
4    False
dtype: bool

请参阅 Flexible Comparisons. .总结一下,我们有

╒════╤════════════╤════════════╕
│    │ Operator   │ Function   │
╞════╪════════════╪════════════╡
│  0 │ >          │ gt         │
├────┼────────────┼────────────┤
│  1 │ >=         │ ge         │
├────┼────────────┼────────────┤
│  2 │ <          │ lt         │
├────┼────────────┼────────────┤
│  3 │ <=         │ le         │
├────┼────────────┼────────────┤
│  4 │ ==         │ eq         │
├────┼────────────┼────────────┤
│  5 │ !=         │ ne         │
╘════╧════════════╧════════════╛

避免使用括号的另一个选项是使用 DataFrame.query (或 eval ):

df.query('A < 5 and B > 5')

   A  B  C
1  3  7  9
3  4  7  6

我有 广泛地 记录在案 query 评估 在里面 Dynamic Expression Evaluation in pandas using pd.eval() .

operator.and_
允许您以功能性方式执行此操作。内部通话 Series.__and__ 它对应于按位运算符。

import operator 

operator.and_(df['A'] < 5, df['B'] > 5)
# Same as,
# (df['A'] < 5).__and__(df['B'] > 5) 

0    False
1     True
2    False
3     True
4    False
dtype: bool

df[operator.and_(df['A'] < 5, df['B'] > 5)]

   A  B  C
1  3  7  9
3  4  7  6

你通常不需要这个,但知道它很有用。

概括起来: np.logical_and (及 logical_and.reduce )
另一种选择是使用 NP逻辑_和 ,也不需要括号:

np.logical_and(df['A'] < 5, df['B'] > 5)

0    False
1     True
2    False
3     True
4    False
Name: A, dtype: bool

df[np.logical_and(df['A'] < 5, df['B'] > 5)]

   A  B  C
1  3  7  9
3  4  7  6

NP逻辑_和 是一个 ufunc (Universal Functions) ,而且大多数UFUNC都有 reduce 方法这意味着更容易概括 logical_and 如果你有多个口罩和。比如说,戴口罩和口罩 m1 m2 m3 具有 & ,你必须这么做

m1 & m2 & m3

然而,一个更简单的选择是

np.logical_and.reduce([m1, m2, m3])

这是非常强大的,因为它可以让你在上面构建更复杂的逻辑(例如,在列表中动态生成掩码并添加所有掩码):

import operator

cols = ['A', 'B']
ops = [np.less, np.greater]
values = [5, 5]

m = np.logical_and.reduce([op(df[c], v) for op, c, v in zip(ops, cols, values)])
m 
# array([False,  True, False,  True, False])

df[m]
   A  B  C
1  3  7  9
3  4  7  6

1-我知道我在反复强调这一点,但请容忍我。这是一个 非常 , 非常 初学者常见的错误,必须解释得非常透彻。


逻辑或

对于 df 上面,假设您希望返回A==3或B==7的所有行。

按位重载 |

df['A'] == 3

0    False
1     True
2     True
3    False
4    False
Name: A, dtype: bool

df['B'] == 7

0    False
1     True
2    False
3     True
4    False
Name: B, dtype: bool

(df['A'] == 3) | (df['B'] == 7)

0    False
1     True
2     True
3     True
4    False
dtype: bool

df[(df['A'] == 3) | (df['B'] == 7)]

   A  B  C
1  3  7  9
2  3  5  2
3  4  7  6

如果还没有,请阅读 逻辑与

或者,也可以使用

df[df['A'].eq(3) | df['B'].eq(7)]

   A  B  C
1  3  7  9
2  3  5  2
3  4  7  6

operator.or_
电话 Series.__or__ 在引擎盖下面。

operator.or_(df['A'] == 3, df['B'] == 7)
# Same as,
# (df['A'] == 3).__or__(df['B'] == 7)

0    False
1     True
2     True
3     True
4    False
dtype: bool

df[operator.or_(df['A'] == 3, df['B'] == 7)]

   A  B  C
1  3  7  9
2  3  5  2
3  4  7  6

np.logical_or
对于两种情况,使用 logical_or :

np.logical_or(df['A'] == 3, df['B'] == 7)

0    False
1     True
2     True
3     True
4    False
Name: A, dtype: bool

df[np.logical_or(df['A'] == 3, df['B'] == 7)]

   A  B  C
1  3  7  9
2  3  5  2
3  4  7  6

对于多个遮罩,请使用 logical_or.reduce :

np.logical_or.reduce([df['A'] == 3, df['B'] == 7])
# array([False,  True,  True,  True, False])

df[np.logical_or.reduce([df['A'] == 3, df['B'] == 7])]

   A  B  C
1  3  7  9
2  3  5  2
3  4  7  6

不符合逻辑

戴上口罩,比如

mask = pd.Series([True, True, False])

如果需要反转每个布尔值(以便最终结果为 [False, False, True] ),则可以使用以下任何方法。

按位 ~

~mask

0    False
1    False
2     True
dtype: bool

同样,表达式需要加括号。

~(df['A'] == 3)

0     True
1    False
2    False
3     True
4     True
Name: A, dtype: bool

这在内部称为

mask.__invert__()

0    False
1    False
2     True
dtype: bool

但不要直接使用它。

operator.inv
内部通话 __invert__ 在这个系列中。

operator.inv(mask)

0    False
1    False
2     True
dtype: bool

np.logical_not
这是numpy的变种。

np.logical_not(mask)

0    False
1    False
2     True
dtype: bool

笔记 NP逻辑_和 可以替代 np.bitwise_and , 逻辑的 具有 bitwise_or logical_not 具有 invert .

5 年前
回复了 cs95 创建的主题 » Python从嵌套字典中获取给定键的值

假设(希望是合理的)您试图找到的值不是包含双引号的字符串( " )在它们中,可以使用regex在JSONified字典中搜索键,并返回相应的值。

import re
import json

def get_value(d, key):
    try:
        # for python-2.x, use,
        # return re.search(r'"{k}": "(.*?)"'.format(key), json.dumps(d)).group(1)
        return re.search(f'"{key}": "(.*?)"', json.dumps(d)).group(1)
    except AttributeError:  # no match
        return np.nan 

get_value(fruit_details, 'statusCode')
# 'S-1'

这是一个普遍的问题。在这种情况下,为 package ,以便您可以安全地参考 包裹 bar 通过 包裹 命名空间,而不会遇到命名冲突。

import package
from package import bar

def foo(bar=42):
    do_something_with_bar(package.bar(bar))

您仍然会导入模块一次,但是现在有两种方法可以引用 酒吧 是的。

5 年前
回复了 cs95 创建的主题 » python round不返回整数

apply 调用 round 在每个列上连续运行。数据框列是 Series 对象,以及 these have a __round__ dunder method defined on them 行为稍有不同。实际上这就是 打电话给 系列 .

round(a[0])

0    1.0
1    1.0
Name: 0, dtype: float64

# Same as,
a[0].__round__()

0    1.0
1    1.0
Name: 0, dtype: float64

与python的典型行为相比 标量:

round(1.5)
# 2

 # Same as,
(1.5).__round__()
# 2

如果你想要同样的行为,使用 applymap .

a.applymap(round)

   0  1
0  1  3
1  1  5

适用于 在每一个 要素 (标量),舍入为整数。

或者,我推荐的解决方案,

a.round().astype(int)

   0  1
0  1  3
1  1  5

请注意,这不会对包含丢失数据(nan)的列进行类型转换。

5 年前
回复了 cs95 创建的主题 » 与python列表一起使用的and运算符[重复]

DR

我们首先总结两个逻辑运算符的两种行为 and or . 这些习语将构成我们下面讨论的基础。

返回第一个错误值(如果有),否则返回最后一个 表达式中的值。

返回第一个truthy值(如果有),否则返回最后一个 表达式中的值。

这些行为也总结在 the docs ,尤其是在这个表中:

enter image description here

返回布尔值的唯一运算符是 not 操作员。


“真实”和“真实”评价

声明

len(args) and max(args) - min(args)

是一个 非常 小精灵 简洁(而且不太可读)的表达方式 args 不为空,返回结果 max(args) - min(args) “,否则返回 0 . 一般来说,它是 if-else 表达式。例如,

exp1 and exp2

应该(大致)翻译成:

r1 = exp1
if not r1:
    r1 = exp2

或者,同等地,

r1 = exp1 if exp1 else exp2

在哪里? exp1 exp2 是任意的python对象,或返回某个对象的表达式。理解逻辑用法的关键 这里的运算符理解它们不限于对布尔值进行操作或返回布尔值。任何具有真实性值的对象都可以在这里进行测试。这包括 int , str , list , dict , tuple , set , NoneType ,以及用户定义的对象。短路规则仍然适用。

但什么是真实?
它指的是在条件表达式中使用对象时如何计算对象。@帕特里克·豪在书中很好地总结了真理。 this post .

所有的价值观都被认为是“真理”,除了以下的 “法西斯”:

  • None
  • False
  • 0.0
  • 0j
  • Decimal(0)
  • Fraction(0, 1)
  • [] 空的 列表
  • {} 空的 双关语
  • () 空的 元组
  • '' 空的 STR
  • b'' 空的 bytes
  • set() 空的 设置
  • 空的 range ,像 range(0)
  • 对象
    • obj.__bool__() 收益率
    • obj.__len__() 收益率

“truthy”值将满足 if while 声明。我们用“truthy”和“falsy”来区别 bool 价值观 True .


怎么 作品

我们以op的问题为基础,讨论了在这些情况下这些运算符是如何实现的。

给出一个函数的定义

def foo(*args):
    ...

如何返回最小值和最大值之间的差异 在一个包含零个或多个参数的列表中?

找到最小值和最大值很容易(使用内置函数!)。这里唯一的障碍是适当地处理参数列表可能为空的角点情况(例如,调用 foo() )我们可以做到这两个在一条线上感谢 操作员:

def foo(*args):
     return len(args) and max(args) - min(args)

foo(1, 2, 3, 4, 5)
# 4

foo()
# 0

自从 如果第一个表达式是 . 注意,如果第一个表达式的计算结果为truthy,则返回值为 总是 结果是 第二个表达式 . 如果第一个表达式的计算结果为false,则返回的结果是第一个表达式的结果。

在上面的函数中,如果 foo 接收一个或多个参数, len(args) 大于 (正数),因此返回的结果是 最大(args)-最小(args) . 哦,如果没有参数被传递, 伦琴(ARGS) 那是假的,而且 返回。

请注意,编写此函数的另一种方法是:

def foo(*args):
    if not len(args):
        return 0

    return max(args) - min(args)

或者,更简洁地说,

def foo(*args):
    return 0 if not args else max(args) - min(args)

当然,这些函数都不执行任何类型检查,所以除非您完全信任所提供的输入, 依赖于这些构造的简单性。


怎么 作品

我解释的工作 以类似的方式,举一个人为的例子。

给出一个函数的定义

def foo(*参数):
…

你将如何完成 返回所有数字 9000 ?

我们使用 来处理这个角落的案子。我们定义 AS:

def foo(*args):
     return [x for x in args if x > 9000] or 'No number over 9000!'

foo(9004, 1, 2, 500)
# [9004]

foo(1, 2, 3, 4)
# 'No number over 9000!'

对列表执行筛选以保留所有数字 九千 . 如果存在任何这样的数字,则列表理解的结果是一个非空列表,这是正确的,因此将返回该列表(此处短路)。如果没有这样的数字,那么列表comp的结果是 [] 这是假的。所以第二个表达式现在被求值(非空字符串)并返回。

使用条件句,我们可以重新编写这个函数,

def foo(*args):
    r = [x for x in args if x > 9000]
    if not r:
        return 'No number over 9000!' 

    return r

和以前一样,这个结构在错误处理方面更加灵活。

5 年前
回复了 cs95 创建的主题 » python数据帧中的部分转换列

为什么不将列保留为字符串?如果您希望“1234”和“0001234”被同等对待,则始终可以去掉前导零。

df.Product_ID.astype(str).str.lstrip('0')

0    ABCD
1    1234
2    1234
3    2345
4    4567
5    EFGH
Name: Product_ID, dtype: object
5 年前
回复了 cs95 创建的主题 » 使用python在3d数组中裁剪3d数组的最快方法

Numpy非常容易支持这样的切片:

dim = 5
x = dim // 2
i,j,k = ind

volume_3d = arr[i-x:i+(dim-x), j-x:j+(dim-x), k-x:k+(dim-x)].copy()

# Your implementation.
dim = 5
x = dim // 2
arr = np.random.randn(7, 7, 7)
el = ind[0]
group = arr[el-x:el+(dim-x)] 
volume_3d = []
for i in group:
    volume_2d = i[ind[1]-x:ind[1]+(dim-x), ind[2]-x:ind[2]+(dim-x)]
    volume_3d.append (volume_2d)

# Proposed in this post.
i,j,k = ind
volume_3d_2 = arr[i-x:i+(dim-x), j-x:j+(dim-x), k-x:k+(dim-x)]

print(np.array_equal(volume_3d, volume_3d_2))
True
6 年前
回复了 cs95 创建的主题 » python自上而下迭代[重复]

x绑定整数对象5。

对, x 是一个变量,包含对整数对象5的引用,该对象 y 也包含对的引用。

返回语句在这里实际返回什么?int对象5? 或者变量名y?或者绑定到对象5?或者别的什么?

准确地说,是 参考 返回到整数对象5。举个例子,看看这个:

In [1]: def foo():
   ...:     y = 5
   ...:     print(id(y))
   ...:     return y
   ...: 

In [2]: x = foo()
4297370816

In [3]: id(x)
Out[3]: 4297370816

如何获取return语句返回的值?

通过访问 参考 return 传回呼叫者。

5 年前
回复了 cs95 创建的主题 » 迭代python字典[重复]

如果您需要单独存储密钥,这里有一个解决方案,它比迄今为止提供的所有其他解决方案都需要更少的输入,使用 Extended Iterable Unpacking (python3.x+)。

newdict = {1: 0, 2: 0, 3: 0}
*k, = newdict

k
# [1, 2, 3]

            ╒═══════════════╤═════════════════════════════════════════╕
            │ k = list(d)   │   9 characters (excluding whitespace)   │
            ├───────────────┼─────────────────────────────────────────┤
            │ k = [*d]      │   6 characters                          │
            ├───────────────┼─────────────────────────────────────────┤
            │ *k, = d       │   5 characters                          │
            ╘═══════════════╧═════════════════════════════════════════╛
5 年前
回复了 cs95 创建的主题 » 迭代python字典[重复]

您也可以使用 列表理解 :

>>> newdict = {1:0, 2:0, 3:0}
>>> [k  for  k in  newdict.keys()]
[1, 2, 3]

或者,更短,

>>> [k  for  k in  newdict]
[1, 2, 3]

注:3.7下的版本不保证订购(订购仍然只是CPython 3.6的一个实现细节)。

4 年前
回复了 cs95 创建的主题 » python中的replace函数给出了错误的结果

replace regex=True

df['Final'] = df['AlmostFinal'].replace(
    [r'KOPL', r'RWP.*?(?=A|B)', r'MM.*(?=A|B)'], 'KOLPOL', regex=True)
df

   Sample AlmostFinal       Final
0       1    KOPLA234  KOLPOLA234
1       1    KOPLA234  KOLPOLA234
2       2    RWPLB253  KOLPOLB253
3       3    MMPLA415  KOLPOLA415
4       3    MMPLA415  KOLPOLA415


pat = ['KOPL', 'RWP', 'MM']
df['Final'] = df['AlmostFinal'].replace(
    [rf'{p}.*(?=A|B)' for p in pat], 'KOLPOL', regex=True)  # need python3.6+
df

   Sample AlmostFinal       Final
0       1    KOPLA234  KOLPOLA234
1       1    KOPLA234  KOLPOLA234
2       2    RWPLB253  KOLPOLB253
3       3    MMPLA415  KOLPOLA415
4       3    MMPLA415  KOLPOLA415

pat = ['KOPL', 'RWPL', 'MMPL']
df['AlmostFinal'].replace(pat, 'KOLPOL', regex=True)

0    KOLPOLA234
1    KOLPOLA234
2    KOLPOLB253
3    KOLPOLA415
4    KOLPOLA415
Name: AlmostFinal, dtype: object