.
以下 Python 代码,用来求出每行第一个不为空的单元格值。
# 求每行第一个不为空的单元格值
import pandas as pd
import numpy as np
df = pd.DataFrame({"第一列":[100, np.NaN, 500, np.NaN, 120 ],
"第二列":[200, 200, np.NaN, 200, 150],
"第三列":[np.NaN, 300, 700, np.NaN, 16]})
print("我是原表:\n", df)
print("\n")
# dataframe 转为 array数组,相当于一行一个小list
c = df.values
df["求值"] = [c[x][np.where(~np.isnan(c[x]))][0] for x in range(len(df))]
print("我是成果表(求值):")
df
代码解析
主要的代码就这一句:
df["求值"] = [c[x][np.where(~np.isnan(c[x]))][0] for x in range(len(df))]
为了详细解释下,我把这句拆成几个语句:
# 以 c[0] 为例,判断 c[0] 中哪些单元格为空, 加上 ~ 符号表示取反,即不为空。
# 输出为一个一维bool数组,即 [False, True, True]
~np.isnan(c[0])
Output:
array([ True, True, False])
# c[0][条件] 表示筛选出符合条件的单元格。
c[0][np.where(~np.isnan(c[0]))]
Output:
array([100., 200.])
c[1][np.where(~np.isnan(c[1]))]
Output:
array([200., 300.])
c[2][np.where(~np.isnan(c[2]))]
Output:
array([500., 700.])
可以看到经过上面几个步骤,每行不为空的单元格都被筛选出了,而我们要求的是第一个值,所以加上索引:
c[2][np.where(~np.isnan(c[2]))][0]
Output:
500.0
接下来利用 for 循环,将所有的行都计算一遍,并将计算结果格式化为list:
[c[x][np.where(~np.isnan(c[x]))][0] for x in range(len(df))]
Output:
[100.0, 200.0, 500.0, 200.0, 120.0]
这就是我们要的不为空的第一个单元格值了。
关于np.where 更全面的用法,见 https://www.zhihu.com/question/62844162/answer/300561552