按列顺序将DataFrame列与列表/序列乘除的无警告实现
问题
我有一个列数N可为0的DataFrame,以及一个与DataFrame列数等长的标量列表。希望按列顺序将DataFrame的各列与列表中对应值相乘或相除。
示例
原始DataFrame
1 2 3 1 1 2 3 2 4 5 6 3 7 8 9
乘数列表[0, 1, 2]
预期结果
1 2 3 1 0 2 6 2 0 5 12 3 0 8 18
测试数据
import pandas as pd idx = [1] # 空DataFrame df_1 = pd.DataFrame({}, index=idx) list_1 = [] series_1 = pd.Series(list_1, dtype=float) # 非空DataFrame(简化为1列) df_2 = pd.DataFrame({1: [1]}, index=idx) list_2 = [12] series_2 = pd.Series(list_2, dtype=float)
遇到的问题
- 使用列表作为乘数时,非空场景正常运行:
但空列表会触发df_2.mul(list_2) # 输出: # 1 # 1 12FutureWarning:df_1.mul(list_1, axis=1) # 警告: # <stdin>:1: FutureWarning: The default dtype for empty Series will be 'object' instead of 'float64' in a future version. Specify a dtype explicitly to silence this warning. # 输出: # Empty DataFrame # Columns: [] # Index: [1] - 改用Series替代列表时,空Series无警告:
但非空Series会匹配索引,导致结果错误:df_1.mul(series_1, axis=1) # 输出: # Empty DataFrame # Columns: [] # Index: [1]df_2.mul(series_2) # 输出: # 0 1 # 1 NaN NaN
需求:按列顺序运算,同时消除警告,保证代码前瞻性。
解决方案
方法1:重置Series索引匹配DataFrame列名
将乘数转为Series时,强制其索引与DataFrame的列名一致,这样mul方法按列匹配时会严格对应顺序,同时规避空场景的警告:
def multiply_by_order(df, multipliers): # 生成与DataFrame列名匹配的乘数Series multiplier_series = pd.Series(multipliers, index=df.columns, dtype=float) return df.mul(multiplier_series, axis=1) # 测试空DataFrame print(multiply_by_order(df_1, list_1)) # 输出: # Empty DataFrame # Columns: [] # Index: [1] # 测试非空DataFrame print(multiply_by_order(df_2, list_2)) # 输出: # 1 # 1 12
方法2:使用NumPy数组作为乘数
NumPy数组不会触发Pandas的索引匹配逻辑,完全按列顺序运算,且空数组不会产生警告,代码更简洁:
import numpy as np # 空DataFrame测试 print(df_1.mul(np.array(list_1), axis=1)) # 输出: # Empty DataFrame # Columns: [] # Index: [1] # 非空DataFrame测试 print(df_2.mul(np.array(list_2), axis=1)) # 输出: # 1 # 1 12
两种方法均能满足需求:既保证按列顺序运算,又消除了空数据场景下的警告,符合代码前瞻性要求。
内容的提问来源于stack exchange,提问作者Jérôme
相关产品推荐
相关产品推荐

