我正在尝试使用在我的日志记录中添加自定义字段LogRecordFactory。我重复调用一个类,每次这样做时,我都想在 init 模块中设置 custom_attribute,以便类中的其余代码将具有此属性。但我无法让它发挥作用。我发现以下内容有效,但它是静态的。
import logging
old_factory = logging.getLogRecordFactory()
def record_factory(*args, **kwargs):
record = old_factory(*args, **kwargs)
record.custom_attribute = "whatever"
return record
logging.basicConfig(format="%(custom_attribute)s - %(message)s")
logging.setLogRecordFactory(record_factory)
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
logging.debug("test")
Run Code Online (Sandbox Code Playgroud)
这将正确输出:
whatever - test
Run Code Online (Sandbox Code Playgroud)
但是,我的用例是 custom_attribute 会有所不同。每次我调用一个特定的函数时,我都想改变它。因此,record_factory 似乎需要传递另一个参数,以便它可以使用新参数返回正确的记录。但我无法弄清楚。我尝试向该函数添加参数,但是当我进行调用时,我得到:
TypeError: __init__() missing 7 required positional arguments: 'name', 'level', 'pathname', 'lineno', 'msg', 'args', and 'exc_info'
Run Code Online (Sandbox Code Playgroud)
*args我认为这与and**kwargs但我真的不知道有关。record_factory另外,为什么调用 by后没有括号logging.setLogRecordFactory?我从来没有见过一个函数像这样工作。
所以我想按行计算数据帧中的空值数量。
请注意,有50列以上,我知道我可以做一个case / when语句来做到这一点,但是我更喜欢一个更整洁的解决方案。
例如,一个子集:
columns = ['id', 'item1', 'item2', 'item3']
vals = [(1, 2, 0, None),(2, None, 1, None),(3,None,9, 1)]
df=spark.createDataFrame(vals,columns)
df.show()
+---+-----+-----+-----+
| id|item1|item2|item3|
+---+-----+-----+-----+
| 1| 2| 'A'| null|
| 2| null| 1| null|
| 3| null| 9| 'C'|
+---+-----+-----+-----+
Run Code Online (Sandbox Code Playgroud)
运行代码后,所需的输出为:
+---+-----+-----+-----+--------+
| id|item1|item2|item3|numNulls|
+---+-----+-----+-----+--------+
| 1| 2| 'A'| null| 1|
| 2| null| 1| null| 2|
| 3| null| 9| 'C'| 1|
+---+-----+-----+-----+--------+
Run Code Online (Sandbox Code Playgroud)
编辑:并非所有非空值都是整数。