1

I am strugling with something in python...

I have a function that when I input a date, it gives me back a column with 30 prices (one in each line) and in index 30 names.

[in] getPrice('14/07/2015')

[out]
apple   10
pear    20
orange  12
banana  23
etc... 

The number of fruit are the same. What I am trying to do is, to loop this function to obtain a big file with the price of these fruits for all the days I have in a list. with the ZIP function I dont really understand how it could work and with the append function it is not 'zipping' the price, meaning it recreate everytime the index, etc.. Any idea? I have a list with all my dates already and the index is the same all along, no other fruit apprear or disapear.

It could look like something

Def Alltogether():
    Alltogether = []
    x = HistoricalDates
    For _ in Historicaldates :
        k = getPrice.... 

and then I block...

I ultimately want something like

print Alltogether

[out]
apple   10 40 60 20 ...
pear    20 20 20 20 ...
orange  12 13 14 29 ...
banana  23 14 41 54 ...
etc... 

I am using panda dataframe.

Thank you very much!

user6457870
  • 247
  • 5
  • 14

2 Answers2

0

This could probably be streamlined by changing the format you get your data in, but here's an example that should get you on your way. I'm totally skipping the zip approach and doing this in more of a Pandas way. For testing I created a dummy function to return random prices for a fixed set of produce:

import pandas as pd
def getPrice(date):
    return pd.Series(np.random.randn(5), index=['apple', 'pear', 'orange', 'nanner', 'etc...'])

And then we can create a pandas dataframe with some dates in it:

df = pd.DataFrame( pd.date_range('1/1/2017', periods=3, freq='D') )
df.columns=['MyDate'] # name the date column

That gives us a simple df with 3 dates:

      MyDate
0 2017-01-01
1 2017-01-02
2 2017-01-03

While iterating over rows is a little less idiomatic than some sort of apply function, I think it's very readable and easy to comprehend to simply iterate over the dates, get the prices, then shove them into a new dataframe and name the column the same as the date. Given your question, I suspect this is your desired output.

outputDF = pd.DataFrame() ## dump results into this df

for index, row in df.iterrows(): #iterate through every row of the date df
    outputDF[row.MyDate] = getPrice(row.MyDate) #shove values into output

which gives us a pretty df like this:

        2017-01-01  2017-01-02  2017-01-03
apple     0.150646    0.209668    0.398204
pear      0.131142    0.046473   -0.261545
orange    0.822508    0.456384   -0.774957
nanner   -0.996102   -0.260049   -0.558503
etc...    0.622459   -0.173556   -0.681957

Per your comment about handling situations where the date is invalid, there are a few ways to handle this. If the getPrice() function throws an error when you pass it a bad date, you might use try/except:

try:
    getPrice(date)
except:
    # do something else... return nulls maybe?

if bad dates don't throw an error but instead they return nulls or an empty list, then just check for that condition after calling getPrice() but before putting it in the dataframe.

JD Long
  • 59,675
  • 58
  • 202
  • 294
  • Hi JD, thank you for your help, it is very useful. I have a last question for you. On my date list some of these dates correspond do nothing, meaning if I input them, the function will not work (10% of the dates arround), since there is too much date I cant delete them, is there a way to say to my function, if the date is wrong, then ignore it and continue? Thank you! – user6457870 Mar 30 '17 at 15:04
0

Is THIS what are you have problem with? Just use '*' to pass a list of lists to zip(). Here an example:

L1=['L1-i1','L1-i2', 'L1-i3', 'L1-i4']
L2=['L2-i1','L2-i2', 'L2-i3', 'L2-i4']
L3=['L3-i1','L3-i2', 'L3-i3', 'L3-i4']

Lalltogether = [L1, L2, L3]

# in Python 3 you should use list() for zip(): 
print( list(zip( *Lalltogether )) )
print( list(zip(  L1, L2, L3   )) )

gives:

[('L1-i1', 'L2-i1', 'L3-i1'), ('L1-i2', 'L2-i2', 'L3-i2'), ('L1-i3', 'L2-i3', 'L3-i3'), ('L1-i4', 'L2-i4', 'L3-i4')]

For more about '*' see Python - use list as function parameters

Community
  • 1
  • 1
Claudio
  • 7,474
  • 3
  • 18
  • 48