简体   繁体   English

在正/负值上拆分列?

[英]Split column on positive/negative values?

So I came across this another little annoying problem, as another obstacle in my first steps of learning python. 因此,我遇到了另一个烦人的小问题,这是学习python的第一步中的另一个障碍。

I have outcome column which has positive/negative/zero values (winnings, loss, no commitment). 我的结果列具有正/负/零值(获胜,亏损,无承诺)。 I would like to split into winnings/loss based on sign, also zeroes would populate zeroes, and negative rows in the new winnings column; 我想根据符号分为彩金/亏损,零也将填零,新彩金栏中为负行; zeroes would populate zeroes and positive rows in the new loss columns. 零将在新损失列中填充零和正行。

DATA. 数据。

g=pd.DataFrame({'OUTCOME':[100,-100,400,-200,-200,-750,-250,1000,0,100,-100]},index=[1,1,2,2,2,3,3,3,4,4,4])

DESIRED OUTPUT. 所需的输出。

g['WINNINGS']=[100,0,400,0,0,0,0,1000,0,100,0]
g['LOSS']=[0,100,0,200,200,750,250,0,0,0,100]

Theres's more than one way to do this, but essentially what you want to do is apply a function that returns 0 if the number is less than or equal to zero, and the input number otherwise. 有多种方法可以执行此操作,但是实际上您要执行的操作是应用一个函数,如果该数字小于或等于零,则该函数返回0,否则返回输入数。 And then do the opposite thing for losses. 然后为损失做相反的事情。 One way is: 一种方法是:

def winnings(value):
    return max(value, 0)

def losses(value):
    return min(value, 0)

df["winnings"] = df["outcome"].map(winnings)
df["loss"] = = df["outcome"].map(losses)

You can use Series.where : 您可以使用Series.where

df["winnings"] = df.OUTCOME.where(df.OUTCOME > 0, 0)
df["loss"] = -1 * df.OUTCOME.where(df.OUTCOME < 0, 0) 
print (df)
   OUTCOME  winnings  loss
1      100       100     0
1     -100         0   100
2      400       400     0
2     -200         0   200
2     -200         0   200
3     -750         0   750
3     -250         0   250
3     1000      1000     0
4        0         0     0
4      100       100     0
4     -100         0   100

Or faster solution with numpy.where : 或者使用numpy.where更快的解决方案:

df["winnings"] = np.where(df.OUTCOME > 0, df.OUTCOME, 0)
df["loss"] = np.where(df.OUTCOME < 0, - df.OUTCOME, 0) 

Timings : 时间

In [68]: %timeit (jez1(df2))
100 loops, best of 3: 3.75 ms per loop

In [69]: %timeit (jez(df1))
100 loops, best of 3: 5.82 ms per loop

In [70]: %timeit (bat(df))
10 loops, best of 3: 134 ms per loop

Code for timings : 计时代码

df=pd.DataFrame({'OUTCOME':[100,-100,400,-200,-200,-750,-250,1000,0,100,-100]},index=[1,1,2,2,2,3,3,3,4,4,4])
print (df)
##[110000 rows x 1 columns]
df = pd.concat([df]*10000).reset_index(drop=True)
df1 = df.copy()
df2 = df.copy()

def winnings(value):
    return max(value, 0)

def losses(value):
    return min(value, 0)

def bat(df):
    df["winnings"] = df.OUTCOME.apply(winnings)
    df["loss"] = - df.OUTCOME.apply(losses)
    return df

def jez(df):
    df["winnings"] = df.OUTCOME.where(df.OUTCOME > 0, 0)
    df["loss"] = -1 * df.OUTCOME.where(df.OUTCOME < 0, 0) 
    return (df)

def jez1(df):
    df["winnings"] = np.where(df.OUTCOME > 0, df.OUTCOME, 0)
    df["loss"] = np.where(df.OUTCOME < 0, - df.OUTCOME, 0) 
    return (df)

print (bat(df))   
print (jez(df1))  
print (jez1(df2))  

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM