我有一个数据框,其值类型为:object
。数据框还包含NaN
值。我想忽略NaN
值,对于该列中的所有其余值,我想计算均值。
均值的计算如下: 上限值= 30 下限值= 0
(上限和下限是固定的,需要为它们计算所有值。)
所以
对于“> 20”,均值=(20 + 30)/ 2 = 25
对于“> 1”,均值=(30 + 1)/2=15.5
对于'<5',平均值=(5 + 0)/ 2 = 2.5
对于'<10',平均值=(10 + 0)/ 2 = 5
数据框:
column1
>20
NaN
<5
12
>1
<10
NaN
8
注意:该列中的上述值为字符串,我想将其转换为数值。
最终转换的数据框应为:
column1
25
NaN
2.5
12
15.5
5
NaN
8
注意:上面的8和12之类的值不会转换,我只想转换以>或<前缀为前缀的那些值,只需要从字符串值转换为数字即可。
答案 0 :(得分:3)
也许有更好的方法,但这也可行:
df['num'] = df.column1.str.extract('(\d+)')
df['sign'] = df.column1.str.extract('([<>])').fillna('=')
def get_avg(row):
if not row.num:
return row.num
elif row.sign == '>':
return (int(row.num)+30)/2
elif row.sign == '>':
return (int(row.num)+0)/2
else:
return row.num
df['avg'] = df.apply(lambda row: get_avg(row), axis=1)
输出:
column1 sign num avg
0 >20 > 20 25
1 NaN = NaN NaN
2 <5 < 5 5
3 12 = 12 12
4 >1 > 1 15.5
5 <10 < 10 10
6 NaN = NaN NaN
7 8 = 8 8
答案 1 :(得分:1)
您可以编写一个函数来计算“自定义平均值”,然后在列上调用apply。
x = np.array([['>20'],[np.NaN],['<5'],['>1'],['<10'],[np.NaN]])
df = pd.DataFrame(x,columns=["column1"])
def myFunc(content, up, low):
try:
if content.isnumeric(): return float(content)
return {
'>': (float(content[1:])+up)/2,
'<': (float(content[1:])+low)/2
}[content[0]]
except:
return np.nan
df["avg"] = df.column1.apply(lambda x: myFunc(x, up=30, low=0))
答案 2 :(得分:1)
下面的代码应用了一个自定义函数,该函数检查每个元素的第一个字符并基于该元素计算平均值。
import numpy as np
import pandas as pd
upper = 30
lower = 0
df = pd.DataFrame({'col1':['>20',np.NaN,'<5','12','>1','<10',np.NaN,'8']})
def avg(val):
if val is not np.NaN:
char = val[0]
if char == '>':
res = (float(val[1:])+upper)/2
elif char == '<':
res = (float(val[1:])+lower)/2
else:
res = float(val)
return res
print(df["col1"].apply(avg))
输出:
0 25.0
1 NaN
2 2.5
3 12.0
4 15.5
5 5.0
6 NaN
7 8.0
答案 3 :(得分:1)
您可以使用np.select
来分配要平均的值。然后,在将column1转换为数字之后,可以求平均值。
import pandas as pd
import numpy as np
lt = df[df.column1.notnull()].column1.str.contains('<')
gt = df[df.column1.notnull()].column1.str.contains('>')
conds = [lt, gt, ~(lt | gt)]
choice = [0, 30, pd.to_numeric(df[df.column1.notnull()].column1, errors='coerce')]
df.loc[df.column1.notnull(), 'column2'] = np.select(conds, choice)
df['column1'] = pd.to_numeric(df.column1.str.replace('<|>', ''))
df['Avg'] = df.mean(axis=1)
输出:
column1 column2 Avg
0 20.0 30.0 25.0
1 NaN NaN NaN
2 5.0 0.0 2.5
3 12.0 12.0 12.0
4 1.0 30.0 15.5
5 10.0 0.0 5.0
6 NaN NaN NaN
7 8.0 8.0 8.0