使用 pandas 检查列的第一个数字
use pandas to check first digit of a column
问题
我需要测试列中每个数字的第一个数字的条件。
条件
是 checkVar 的第一个数字大于 5
或者
是 checkVar 的第一个数字小于 2
然后设置 newVar=1
解决方案
有人以为我是把它转换成一个字符串,去掉空格,然后取 [0],但我想不出代码。
也许是这样的,
df.ix[df.checkVar.str[0:1].str.contains('1'),'newVar']=1
这不是我想要的,出于某种原因我得到了这个错误
invalid index to scalar variable.
测试我的原始变量我得到应该满足条件的值
df.checkVar.value_counts()
301 62
1 15
2 5
999 3
dtype: int64
理想情况下它看起来像这样:
checkVar newVar
NaN 1 nan
2 nan
3 nan
4 nan
5 301.0
6 301.0
7 301.0
8 301.0
9 301.0
10 301.0
11 301.0
12 301.0
13 301.0
14 1.0 1
15 1.0 1
更新
我的最终解决方案,因为实际问题更复杂
w = df.EligibilityStatusSP3.dropna().astype(str).str[0].astype(int)
v = df.EligibilityStatusSP2.dropna().astype(str).str[0].astype(int)
u = df.EligibilityStatusSP1.dropna().astype(str).str[0].astype(int)
t = df.EligibilityStatus.dropna().astype(str).str[0].astype(int) #get a series of the first digits of non-nan numbers
df['MCelig'] = ((t < 5)|(t == 9)|(u < 5)|(v < 5)|(w < 5)).astype(int)
df.MCelig = df.MCelig.fillna(0)
当您不确定如何继续时,稍微分解一下步骤会很有帮助。
def checkvar(x):
s = str(x)
first_d = int(s[0])
if first_d < 2 or first_d > 5:
return 1
else:
return 0
将 "else: return" 值更改为您想要的任何值(例如,"else: pass")。另外,如果你想创建一个新列:
*更新 - 我之前没有注意到 NaN。我看到即使使用 dropna(),您仍然遇到问题。以下内容对您有用吗,就像对我一样吗?
df = pd.DataFrame({'old_col': [None, None, None, 13, 75, 22, 51, 61, 31]})
df['new_col'] = df['old_col'].dropna().apply(checkvar)
df
如果是这样也许您数据中的问题与 'old_col' 的数据类型有关?您是否尝试过先将其转换为浮动?
df['old_col'] = df['old_col'].astype('float')
t = df.checkVar.dropna().astype(str).str[0].astype(int) #get a series of the first digits of non-nan numbers
df['newVar'] = ((t > 5) | (t < 2)).astype(int)
df.newVar = df.newVar.fillna(0)
这可能稍微好一点,不确定,但是另一种非常相似的方法。
t = df.checkVar.dropna().astype(str).str[0].astype(int)
df['newVar'] = 0
df.newVar.update(((t > 5) | (t < 2)).astype(int))
问题
我需要测试列中每个数字的第一个数字的条件。
条件
是 checkVar 的第一个数字大于 5
或者
是 checkVar 的第一个数字小于 2
然后设置 newVar=1
解决方案
有人以为我是把它转换成一个字符串,去掉空格,然后取 [0],但我想不出代码。
也许是这样的,
df.ix[df.checkVar.str[0:1].str.contains('1'),'newVar']=1
这不是我想要的,出于某种原因我得到了这个错误
invalid index to scalar variable.
测试我的原始变量我得到应该满足条件的值
df.checkVar.value_counts()
301 62
1 15
2 5
999 3
dtype: int64
理想情况下它看起来像这样:
checkVar newVar
NaN 1 nan
2 nan
3 nan
4 nan
5 301.0
6 301.0
7 301.0
8 301.0
9 301.0
10 301.0
11 301.0
12 301.0
13 301.0
14 1.0 1
15 1.0 1
更新
我的最终解决方案,因为实际问题更复杂
w = df.EligibilityStatusSP3.dropna().astype(str).str[0].astype(int)
v = df.EligibilityStatusSP2.dropna().astype(str).str[0].astype(int)
u = df.EligibilityStatusSP1.dropna().astype(str).str[0].astype(int)
t = df.EligibilityStatus.dropna().astype(str).str[0].astype(int) #get a series of the first digits of non-nan numbers
df['MCelig'] = ((t < 5)|(t == 9)|(u < 5)|(v < 5)|(w < 5)).astype(int)
df.MCelig = df.MCelig.fillna(0)
当您不确定如何继续时,稍微分解一下步骤会很有帮助。
def checkvar(x):
s = str(x)
first_d = int(s[0])
if first_d < 2 or first_d > 5:
return 1
else:
return 0
将 "else: return" 值更改为您想要的任何值(例如,"else: pass")。另外,如果你想创建一个新列:
*更新 - 我之前没有注意到 NaN。我看到即使使用 dropna(),您仍然遇到问题。以下内容对您有用吗,就像对我一样吗?
df = pd.DataFrame({'old_col': [None, None, None, 13, 75, 22, 51, 61, 31]})
df['new_col'] = df['old_col'].dropna().apply(checkvar)
df
如果是这样也许您数据中的问题与 'old_col' 的数据类型有关?您是否尝试过先将其转换为浮动?
df['old_col'] = df['old_col'].astype('float')
t = df.checkVar.dropna().astype(str).str[0].astype(int) #get a series of the first digits of non-nan numbers
df['newVar'] = ((t > 5) | (t < 2)).astype(int)
df.newVar = df.newVar.fillna(0)
这可能稍微好一点,不确定,但是另一种非常相似的方法。
t = df.checkVar.dropna().astype(str).str[0].astype(int)
df['newVar'] = 0
df.newVar.update(((t > 5) | (t < 2)).astype(int))