Pandas - 从具有混合数据类型的不同数据框中减去列



我有两个从不同.csv导入的数据框。

df10=pd.read_csv(path10, usecols=["Registros validados"])
df25=pd.read_csv(path25, usecols=["Registros validados"])

它们是 173k 行和一列,其中包含的数据是数字,但有一些空的测量值,当从csv读取时被视为空字符串(与此相关的数字也是如此(。

我需要做的很简单,只有当两列都有一个数字并创建第三个数据帧时,我才需要减去它们。

找到了我从这个网页的其他帖子中得到的两个想法。以下两个是有效的(没有给我错误(,因为我主要看到的是.apply,但这总是用于使用的列来自同一数据帧,它们不在这里。

"有效"的选项是

list(map(subs_PM, dfpm10, dfpm25))
# Returns ['']

dfpm10.combine(dfpm25, func=subs_PM)
# Actually returns a data frame, but is always empty with ''. 

使用的减法函数是

def subs_PM_old(pm10, pm25):
try: # Thinking the strings would fail at this
pm10=int(pm10)
pm25=int(pm25)
except: 
return ' '
else:
return pm10-pm25

认为减法的差异可能是由于数据帧不是数字。所以我做了以下操作将数字转换为数字并将字符串保留为字符串。

df10=df10.apply(pd.to_numeric, errors='ignore')
df25=df25.apply(pd.to_numeric, errors='ignore')

并将函数更新为

def subs_PM(pm10, pm25):
boolpm10=isinstance(pm10, (int, long, float, complex)) and not isinstance(pm10, bool)
boolpm25=isinstance(pm10, (int, long, float, complex)) and not isinstance(pm25, bool)
if boolpm10 and boolpm25:
return pm10-pm25
else:
return ''

但什么都没有改变

似乎正在发生的事情是,在这两种情况下,减去函数仅用于第一行,然后假设其余项目也是如此。

有没有办法改变这种状况?


显然这些不是我的数据帧,但请考虑使用这个

df1 = pd.DataFrame({1: range(10)})
df2 = pd.DataFrame({1: [2, 3, '', '', 2, 1, '', 6, 2, 3]})
df1.combine(df2, func=subs_PM)
df1.combine(df2, func=subs_PM_old)
list(map(subs_PM, df1, df2))
list(map(subs_PM_old, df1, df2))

试试这个:

def subs_PM(pm10, pm25):
#pm10 and pm25 are series... not a single number
#print(pm10)
try:
pm10=pd.to_numeric(pm10)
pm25=pd.to_numeric(pm25)
return pm10-pm25
except:
return None
df1 = pd.DataFrame({1: range(10)})
df2 = pd.DataFrame({1: [2, 3, '', '', 2, 1, '', 6, 2, 3]})
df1.combine(df2, func=subs_PM)

为了检查所有变体,我按如下方式定义了源数据帧:

df1 = pd.DataFrame({1: [0, '',  2,  3, 4, 5, '', 7, 8, 9]})
df2 = pd.DataFrame({1: [2,  3, '', '', 2, 1,  5, 6, 2, 3]})

目标是拥有"对"参数,其中df1DF2可以包含一个字符串(要从最终结果中排除(。

初始操作包括:

  • 联接两个数据帧,
  • NaN替换空字符串并删除它们,
  • 将类型更改回int
  • 为两列指定不同的名称。

执行此操作的代码是:

res = df1.join(df2, rsuffix='_2').replace('', np.nan).dropna().astype(int)
res.columns=['c1', 'c2']

对于我的源数据,结果是:

c1  c2
0   0   2
4   4   2
5   5   1
7   7   6
8   8   2
9   9   3

然后只需计算差异,将其保存在另一列中:

res['dif'] = res.c1 - res.c2

最终结果是:

c1  c2  dif
0   0   2   -2
4   4   2    2
5   5   1    4
7   7   6    1
8   8   2    6
9   9   3    6

如果需要,请删除c1c2列。

相关内容

最新更新