简体   繁体   中英

Pandas Dataframe row by row fill new column

I am trying to perform a row by row operation on a Pandas Dataframe as such:

df = pd.DataFrame(columns=['Product', 'Price', 'Buy', 'Sell'])
df.loc[len(df.index)] = ["Apple", 1.50, 3, 2]
df.loc[len(df.index)] = ["Banana", 0.75, -8, 4]
df.loc[len(df.index)] = ["Carrot", 2.00, -6, -3]
df.loc[len(df.index)] = ["Blueberry", 0.05, 5, 6]

Basically I want to create a new column "Ratio" that divides Price/Buy or Price/Sell, depending on which abs(buy) or abs(sell) is greater. I am not really sure how to do this...would I use an apply function?

Thanks!

You can directly use column indexing ( http://pandas.pydata.org/pandas-docs/stable/indexing.html ) to compare and filter ratios.

buy_ratio = (abs(df["Buy"])  > abs(df["Sell"])) * df["Price"] / df["Buy"]
sell_ratio = (abs(df["Buy"])  <= abs(df["Sell"])) * df["Price"] / df["Sell"]
df["Ratio"] = buy_ratio + sell_ratio

In this case,

  1. The condition (abs(df["Buy"]) > abs(df["Sell"])) gives a 0/1 valued column depending on whether buy or sell is greater. You multiply that column by Price/Buy. If Sell price is high, the multiplication will be zero.
  2. Perform a symmetric operation for Sell
  3. Finally, add them together and directly set the column named "Ratio" using indexing.

Edit

Here is the solution using apply - First define a function operating in rows of the DataFrame.

def f(row):
  if abs(row["Buy"]) > abs(row["Sell"]):
    return row["Price"] / row["Buy"]
  else:
    return row["Price"] / row["Sell"]

Finally, set the Ratio column appropriately using apply.

df["Ratio"] = df.apply(f, axis=1)

What about something like this? Double check the logic.

df['Ratio'] = df.apply(
    lambda x: (x.Price / x.Sell) if abs(x.Buy) < abs(x.Sell) else (x.Price / x.Buy),
    axis=1)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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