3
\$\begingroup\$

Using pandas and Python 3, information about a simple timeseries data set is being processed. Within the span of .5 seconds, 3 names are being said. We record the onset of each utterance, the length of the name, and the sex of the referent, and store it in a sparse Pandas DataFrame.

We also construct a second DataFrame with a non-sparse time index and merge the two, leading to a sparse DataFrame containing just 3 events and a bunch of empty fields.

import pandas as pd

df1 = pd.DataFrame()
df1["time"] = range(0,50)
df2 = pd.DataFrame({'time' : [7, 17, 30], 'name' : ['Alex','Julia','Lex'], 'sex' : ['m','f','f'], 'len' : [4, 5, 3]})

big_df = pd.merge(df1, df2, on='time', how='outer')

(This may not be optimal, but it's sufficient for the demonstration.) Now, the DataFrame should be expanded to include information about each name not only at the time where it was uttered, but also at preceding and following time points. At these lags (say, from 5 msec before to 10 msec after), we want to store that 5 (4, 3, ...) msec later (1, 2 3, ... earlier), a name of a given length, referring to a person of a given sex, is uttered.

factors = ['name', 'sex', 'len']

tdeltas = range(-5,10)
for i in df2.index:
    t0 = df2.loc[i,'time']
    for factor in factors:
        value = df2.loc[i,factor]
        for tdelta in tdeltas:
            tx = int(round(t0)+tdelta)
            big_df.loc[tx,factor+"@"+str(tdelta)] = value

This works:

>>>big_df.head(50)
    time  len   name  sex name@-5 sex@-5  len@-5 name@-4 sex@-4  len@-4 name@-3 sex@-3  len@-3 name@-2 sex@-2  len@-2 name@-1 sex@-1  len@-1 name@0
0      0  NaN    NaN  NaN     NaN    NaN     NaN     NaN    NaN     NaN     NaN    NaN     NaN     NaN    NaN     NaN     NaN    NaN     NaN    NaN ...
1      1  NaN    NaN  NaN     NaN    NaN     NaN     NaN    NaN     NaN     NaN    NaN     NaN     NaN    NaN     NaN     NaN    NaN     NaN    NaN ...
2      2  NaN    NaN  NaN    Alex      m       4     NaN    NaN     NaN     NaN    NaN     NaN     NaN    NaN     NaN     NaN    NaN     NaN    NaN ...
3      3  NaN    NaN  NaN     NaN    NaN     NaN    Alex      m       4     NaN    NaN     NaN     NaN    NaN     NaN     NaN    NaN     NaN    NaN ...
4      4  NaN    NaN  NaN     NaN    NaN     NaN     NaN    NaN     NaN    Alex      m       4     NaN    NaN     NaN     NaN    NaN     NaN    NaN ...
5      5  NaN    NaN  NaN     NaN    NaN     NaN     NaN    NaN     NaN     NaN    NaN     NaN    Alex      m       4     NaN    NaN     NaN    NaN ...
6      6  NaN    NaN  NaN     NaN    NaN     NaN     NaN    NaN     NaN     NaN    NaN     NaN     NaN    NaN     NaN    Alex      m       4    NaN ...
7      7    4   Alex    m     NaN    NaN     NaN     NaN    NaN     NaN     NaN    NaN     NaN     NaN    NaN     NaN     NaN    NaN     NaN   Alex ...
8      8  NaN    NaN  NaN     NaN    NaN     NaN     NaN    NaN     NaN     NaN    NaN     NaN     NaN    NaN     NaN     NaN    NaN     NaN    NaN ...
9      9  NaN    NaN  NaN     NaN    NaN     NaN     NaN    NaN     NaN     NaN    NaN     NaN     NaN    NaN     NaN     NaN    NaN     NaN    NaN ...
10    10  NaN    NaN  NaN     NaN    NaN     NaN     NaN    NaN     NaN     NaN    NaN     NaN     NaN    NaN     NaN     NaN    NaN     NaN    NaN ...
11    11  NaN    NaN  NaN     NaN    NaN     NaN     NaN    NaN     NaN     NaN    NaN     NaN     NaN    NaN     NaN     NaN    NaN     NaN    NaN ...
12    12  NaN    NaN  NaN   Julia      f       5     NaN    NaN     NaN     NaN    NaN     NaN     NaN    NaN     NaN     NaN    NaN     NaN    NaN ...
13    13  NaN    NaN  NaN     NaN    NaN     NaN   Julia      f       5     NaN    NaN     NaN     NaN    NaN     NaN     NaN    NaN     NaN    NaN ...
14    14  NaN    NaN  NaN     NaN    NaN     NaN     NaN    NaN     NaN   Julia      f       5     NaN    NaN     NaN     NaN    NaN     NaN    NaN ...
15    15  NaN    NaN  NaN     NaN    NaN     NaN     NaN    NaN     NaN     NaN    NaN     NaN   Julia      f       5     NaN    NaN     NaN    NaN ...
16    16  NaN    NaN  NaN     NaN    NaN     NaN     NaN    NaN     NaN     NaN    NaN     NaN     NaN    NaN     NaN   Julia      f       5    NaN ...
17    17    5  Julia    f     NaN    NaN     NaN     NaN    NaN     NaN     NaN    NaN     NaN     NaN    NaN     NaN     NaN    NaN     NaN  Julia ...

Now, we wish to repeated this operation to a much larger data set, with thousands of different names in the span of up to an hour, longer lags, and much more information about each name. The nested for loop is much too slow for this task, taking hours to run. Can it be sped up by orders of magnitude?

\$\endgroup\$
  • \$\begingroup\$ I edited the script slightly to shift one database query up one level of the loop. It works faster already, although not fast enough. \$\endgroup\$ – jona Sep 20 '14 at 19:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.