Optimizing using Pandas Data Frame - python-3.x

I have the following function that loads a csv into a data frame then does some calculations. It takes about 4-5 minutes to do calculation on the csv with a little over 100,000 lines. I was hoping there is a faster way.
def calculate_adeck_errors(in_file):
print(f'Starting Data Calculations: {datetime.datetime.now().strftime("%I:%M%p on %B %d, %Y")}')
pd.set_option('display.max_columns', 12)
# read in the raw csv
adeck_df = pd.read_csv(in_file)
#print(adeck_df)
#extract only the carq items and remove duplicates
carq_data = adeck_df[(adeck_df.MODEL == 'CARQ') & (adeck_df.TAU == 0)].drop_duplicates(keep='last')
#print(carq_data)
#remove carq items from original
final_df = adeck_df[adeck_df.MODEL != 'CARQ']
#print(final_df)
row_list = []
for index, row in carq_data.iterrows():
position_time = row['POSDATETIME']
for index, arow in final_df.iterrows():
if arow['POSDATETIME'] == position_time:
# match, so do calculations
storm_id = arow['STORMID']
model_base_time = arow['MODELDATETIME']
the_hour = arow['TAU']
the_model = arow['MODEL']
point1 = float(row['LAT']), float(row['LON'])
point2 = float(arow['LAT']), float(arow['LON'])
if arow['LAT'] == 0.0:
dist_error = None
else:
dist_error = int(round(haversine(point1, point2, miles=True)))
if arow['WIND'] != 0:
wind_error = int(abs(int(row['WIND']) - int(arow['WIND'])))
else: wind_error = None
if arow['PRES'] != 0:
pressure_error = int(abs(int(row['PRES']) - int(arow['PRES'])))
else:
pressure_error = None
lat_carq = row['LAT']
lon_carq = row['LON']
lat_model = arow['LAT']
lon_model = arow['LON']
wind_carq = row['WIND']
wind_model = arow['WIND']
pres_carq = row['PRES']
pres_model = arow['PRES']
row_list.append([storm_id, model_base_time, the_model, the_hour, lat_carq, lon_carq, lat_model, lon_model, dist_error,
wind_carq, wind_model, wind_error, pres_carq, pres_model, pressure_error])
result_df = pd.DataFrame(row_list)
result_df = result_df.where((pd.notnull(result_df)), None)
result_cols = ['StormID', 'ModelBasetime', 'Model' , 'Tau',
'LatCARQ', 'LonCARQ', 'LatModel', 'LonModel', 'DistError',
'WindCARQ', 'WindModel','WindError',
'PresCARQ', 'PresModel','PresError']
result_df.columns = result_cols
calculate_adeck_errors(infile)
To clarify what I'm doing:
1. The CARQ entries are the control (actual).
2. The other models are the guesses.
3. I'm comparing the control (CARQ) to the guesses to see what their errors are.
4. The basis of the comparison is the MODELBASETIME = POSBASETIME
4. A sample file I'm processing is here: http://vortexweather.com/downloads/adeck/aal062018.csv
I was hoping there is a faster way than i'm doing it, or another pandas method besides iterrows
Many thanks for suggestion.
Bryan

This code takes about 10 seconds to run your entire dataset!
The code looks very similar to what you have written, with the exception that all of the operations within the main_function have been vectorized. See Fast, Flexible, Easy and Intuitive: How to Speed Up Your Pandas Projects
2018-09-13_adeck_error_calculations.ipynb
import pandas as pd
import numpy as np
import datetime
from haversine import haversine
def main_function(df, row):
"""
The main difference here is that everything is vectorized
Returns: DataFrame
"""
df_new = pd.DataFrame()
df_storage = pd.DataFrame()
pos_datetime = df.POSDATETIME.isin([row['POSDATETIME']]) # creates a Boolean map
array_len = len(pos_datetime)
new_index = pos_datetime.index
df_new['StormID'] = df.loc[pos_datetime, 'STORMID']
df_new['ModelBaseTime'] = df.loc[pos_datetime, 'MODELDATETIME']
df_new['Model'] = df.loc[pos_datetime, 'MODEL']
df_new['Tau'] = df.loc[pos_datetime, 'TAU']
# Distance
df_new['LatCARQ'] = pd.DataFrame(np.full((array_len, 1), row['LAT']), index=new_index).loc[pos_datetime, 0]
df_new['LonCARQ'] = pd.DataFrame(np.full((array_len, 1), row['LON']), index=new_index).loc[pos_datetime, 0]
df_new['LatModel'] = df.loc[pos_datetime, 'LAT']
df_new['LonModel'] = df.loc[pos_datetime, 'LON']
def calc_dist_error(row):
return round(haversine((row['LatCARQ'], row['LonCARQ']), (row['LatModel'], row['LonModel']), miles=True)) if row['LatModel'] != 0.0 else None
df_new['DistError'] = df_new.apply(calc_dist_error, axis=1)
# Wind
df_new['WindCARQ'] = pd.DataFrame(np.full((array_len, 1), row['WIND']), index=new_index).loc[pos_datetime, 0]
df_new['WindModel'] = df.loc[pos_datetime, 'WIND']
df_storage['row_WIND'] = pd.DataFrame(np.full((array_len, 1), row['WIND']), index=new_index).loc[pos_datetime, 0]
df_storage['df_WIND'] = df.loc[pos_datetime, 'WIND']
def wind_error_calc(row):
return (row['row_WIND'] - row['df_WIND']) if row['df_WIND'] != 0 else None
df_new['WindError'] = df_storage.apply(wind_error_calc, axis=1)
# Air Pressure
df_new['PresCARQ'] = pd.DataFrame(np.full((array_len, 1), row['PRES']), index=new_index).loc[pos_datetime, 0]
df_new['PresModel'] = df.loc[pos_datetime, 'PRES']
df_storage['row_PRES'] = pd.DataFrame(np.full((array_len, 1), row['PRES']), index=new_index).loc[pos_datetime, 0]
df_storage['df_PRES'] = df.loc[pos_datetime, 'PRES']
def pres_error_calc(row):
return abs(row['row_PRES'] - row['df_PRES']) if row['df_PRES'] != 0 else None
df_new['PresError'] = df_storage.apply(pres_error_calc, axis=1)
del(df_storage)
return df_new
def calculate_adeck_errors(in_file):
"""
Retruns: DataFrame
"""
print(f'Starting Data Calculations: {datetime.datetime.now().strftime("%I:%M:%S%p on %B %d, %Y")}')
pd.set_option('max_columns', 20)
pd.set_option('max_rows', 300)
# read in the raw csv
adeck_df = pd.read_csv(in_file)
adeck_df['MODELDATETIME'] = pd.to_datetime(adeck_df['MODELDATETIME'], format='%Y-%m-%d %H:%M')
adeck_df['POSDATETIME'] = pd.to_datetime(adeck_df['POSDATETIME'], format='%Y-%m-%d %H:%M')
#extract only the carq items and remove duplicates
carq_data = adeck_df[(adeck_df.MODEL == 'CARQ') & (adeck_df.TAU == 0)].drop_duplicates(keep='last')
print('Len carq_data: ', len(carq_data))
#remove carq items from original
final_df = adeck_df[adeck_df.MODEL != 'CARQ']
print('Len final_df: ', len(final_df))
df_out_new = pd.DataFrame()
for index, row in carq_data.iterrows():
test_df = main_function(final_df, row) # function call
df_out_new = df_out_new.append(test_df, sort=False)
df_out_new = df_out_new.reset_index(drop=True)
df_out_new = df_out_new.where((pd.notnull(df_out_new)), None)
print(f'Finishing Data Calculations: {datetime.datetime.now().strftime("%I:%M:%S%p on %B %d, %Y")}')
return df_out_new
in_file = 'aal062018.csv'
df = calculate_adeck_errors(in_file)
>>>Starting Data Calculations: 02:18:30AM on September 13, 2018
>>>Len carq_data: 56
>>>Len final_df: 137999
>>>Finishing Data Calculations: 02:18:39AM on September 13, 2018
print(len(df))
>>>95630
print(df.head(20))
Please don't forget to check the accepted solution. Enjoy!

Looks like you are creating two dataframes out of the same dataframe, and then processing them. Two things that may cut your time.
First, you are iterating over both dataframes and checking for a condition:
for _, row in carq_data.iterrows():
for _, arow in final_df.iterrows():
if arow['POSDATETIME'] == row['POSDATETIME']:
# do something by using both tables
This is essentially an implementation of a join. You are joining carq_data with final_df on 'POSDATETIME'.
As a first step, you should merge the tables:
merged = carq_data.merge(final_df, on=['POSDATETIME'])
At this point you will get multiple rows for each similar 'POSDATETIME'. In the below, let's assume column b is POSDATETIME:
>>> a
a b
0 1 11
1 1 33
>>> b
a b
0 1 2
1 1 3
2 1 4
>>> merged = a.merge(b, on=['a'])
>>> merged
a b_x b_y
0 1 11 2
1 1 11 3
2 1 11 4
3 1 33 2
4 1 33 3
5 1 33 4
Now, to do your conditional calculations, you can use the apply() function.
First, define a function:
def calc_dist_error(row):
return int(round(haversine(row['b_x'], row['b_y'], miles=True))) if row['a'] != 0.0 else None
Then apply it to every row:
merged['dist_error'] = merged.apply(calc_dist_error, axis=1)
Continuing my small example:
>>> merged['c'] = [1, 0, 0, 0, 2, 3]
>>> merged
a b_x b_y c
0 1 11 2 1
1 1 11 3 0
2 1 11 4 0
3 1 33 2 0
4 1 33 3 2
5 1 33 4 3
>>> def foo(row):
... return row['b_x'] - row['b_y'] if row['c'] != 0 else None
...
>>> merged['dist_error'] = merged.apply(foo, axis=1)
>>> merged
a b_x b_y c dist_error
0 1 11 2 1 9.0
1 1 11 3 0 NaN
2 1 11 4 0 NaN
3 1 33 2 0 NaN
4 1 33 3 2 30.0
5 1 33 4 3 29.0
This should help you reduce run time (see also this for how to check using %timeit). Hope this helps!

Related

Append the columns and put one after other

I have the following dataframe:
a1
p1
a2
p2
a3
p3
...
1
2
3
4
5
6
...
7
8
9
10
11
12
...
And, I want to create a dataframe like this:
a
p
1
2
7
8
3
4
9
10
5
6
11
12
...
...
Do you need something like this?
import pandas as pd
import random
a = [random.randint(1,100) for i in range(178) ]
b = [random.randint(1,100) for i in range(178) ]
#Original DF
df = pd.DataFrame({"0": a, "1": b})
#New DF
cf = pd.DataFrame()
cf["Actual Value"] = df["0"]
cf["Predicted Value"] = df["1"]
cf["Error Value"] = df["0"] - df["1"]
cf["Id"] = ["Bin" + str(i + 1) for i in range(178) ]
I misunderstand you with previous one.
This should fit you:
import pandas as pd
import random
#Original DF
d = {}
for i in range(int(178)):
a = [random.randint(1,100) for i in range(10) ]
b = [random.randint(1,100) for i in range(10) ]
d["Bin " + str(i+1)] = pd.DataFrame({"0": a, "1": b})
con = pd.concat(d, axis=1)
colum = []
for i in range(178*2):
if i%2 == 0:
colum.append("0")
else:
colum.append("1")
con.columns = colum
#New DF
result = []
count = 0
for i in range(0,178*2,2):
a = con.iloc[:,[i,i+1]]
a["Error"] = a["0"] - a["1"]
a["Bucked"] = "Bin: " + str(count)
result.append(a)
count = count + 1
result = pd.concat(result)
result
Result image:

Group by mean for element with value >0

df=pd.DataFrame({"x":[1,2,3,0],"y":[1,1,1,1]})
df.groupby("y").agg(x_sum=("x",np.mean))
This code gives average of x, the output is 1.5 ((1+2+3+0)/4=1.5)
but I want average of x where the number of larger than 0, so the output should be (1+2+3)/3=2.
How should I address it?
Replace not greater like 0 in x column to NaN:
df.x = df.x.where(df.x.gt(0))
#alternative
#df.x = df.x.mask(df.x.le(0))
print (df)
x y
0 1.0 1
1 2.0 1
2 3.0 1
3 NaN 1
df1 = df.groupby("y").agg(x_sum=("x",np.mean))
print (df1)
x_sum
y
1 2.0
You can write and use your custom function. Example:
import pandas as pd
import numpy as np
def mean_without_zero_values(values):
vals = [v for v in values if v > 0]
return np.mean(vals)
df=pd.DataFrame({"x":[1,2,3,0],"y":[1,1,1,1]})
result = df.groupby("y").agg(x_sum=("x",mean_without_zero_values))
print(result)
# output
# x_sum
# y
# 1 2

Error: TypeError: cannot perform reduce with flexible type

i am using python version 3.7.Below is the code in which I am performing operation along the rows. i want the mean of the data which are along the rows but I get an error. i am new to numpy and python. i am reading the data from text file.
My code is:
import numpy as np
def getIndexFromDatetime(date_from, date_to):
'''date_from = [2, 10] : 10oclock of day2
'''
if date_from[1] > 24 or date_to[1] > 24: print('error')
start = (date_from[0] - 1) * 48 + date_from[1] * 2
end = (date_to[0] - 1) * 48 + date_to[1] * 2
return [start, end]
def is_num(s):
return s.replace(',', '').replace('.', '').replace('-', '').isnumeric()
def get_dataset(fpath):
with open(fpath, 'r') as f:
cnt = 0
DataWeather = {}
header = []
dtime = []
temp1 = []
temp2 = []
for line in f:
terms = line.split('\t')
#print(terms)
if cnt == 0: header1 = terms
if cnt == 1: header2 = terms
#header.append(terms[3])
cnt += 1
if cnt == 2:
for i in range(len(header1)):
header.append(header1[i]+header2[i])
#print(header)
for i in range(len(terms)):
DataWeather[header[i]] = []
#break
if cnt > 2:
for i in range(len(terms)):
if is_num(terms[i]):
DataWeather[header[i]].append(float(terms[i]))
else:
DataWeather[header[i]].append(terms[i])
for i in range(len(DataWeather[header[0]])):
dtime.append(DataWeather[header[0]][i]+' '+DataWeather[header[1]][i])
return DataWeather, header
def get_data(dataset, header, idx):
y = dataset[header][idx[0]:idx[1]]
return y
data_dir = 'weather_data'
month = 3
day = list(range(1,10))
header_idx = [2,3,4,5,7,16]
for d in day:
print(d)
dtime_from = [d, 9]
dtime_to = [d, 18]
dtime_idx = getIndexFromDatetime(dtime_from, dtime_to)
fpath = '{0}/2019-{1:02}.txt'.format(data_dir, month)
dataset, header = get_dataset(fpath)
for h in header_idx:
print(fpath)
print(header[h], dtime_from, dtime_to, dtime_idx)
data = get_data(dataset, header[h], dtime_idx)
#data= list(map(float,np.array(data)))
#data = map(np.array(data, dtype=np.float))
print(data)
print(np.mean(data))
i am getting the following error:
ret = umr_sum(arr, axis, dtype, out, keepdims)
TypeError: cannot perform reduce with flexible type
i also tried some functions like "map" and "list" as commented in the code still it gives error of converting string to float.

Exporting a cellular automaton data to csv in Python

I've been working in Reaction-Diffusion cellular automata with the cellpylib library for a course in my university (I wrote it all in one script so you don't have to install/download anything). I'd like to save the evolution of the automata data to a csv file to run some statistics. That is, I'd like to save the data in columns where the first column is 'number of "1"' and the second column: 'time steps'.
Thus, I need help in:
(1) Creating a variable that saves the amount of '1' per time step (I think so).
(2) I need to export all that data to a csv file (number of "1" and the corresponding iteration, from 1 to time_steps in the code below).
The code is the following.
#Libraries
import matplotlib
matplotlib.matplotlib_fname()
import matplotlib.pyplot as plt
import matplotlib as mpl
import matplotlib.animation as animation
import numpy as np
import csv
# Conditions
#############################
theta = 1 # this is the condition for Moore neighbourhood
Int = 100 # this is the iteration speed (just for visualization)
time_steps = 100 # Iterations
size = 8 # this is the size of the matrix (8x8)
#############################
# Definitions
def plot2d_animate(ca, title=''):
c = mpl.colors.ListedColormap(['green', 'red', 'black', 'gray'])
n = mpl.colors.Normalize(vmin=0,vmax=3)
fig = plt.figure()
plt.title(title)
im = plt.imshow(ca[0], animated=True, cmap=c, norm=n)
i = {'index': 0}
def updatefig(*args):
i['index'] += 1
if i['index'] == len(ca):
i['index'] = 0
im.set_array(ca[i['index']])
return im,
ani = animation.FuncAnimation(fig, updatefig, interval=Int, blit=True)
plt.show()
def init_simple2d(rows, cols, val=1, dtype=np.int):
x = np.zeros((rows, cols), dtype=dtype)
x[x.shape[0]//2][x.shape[1]//2] = val
return np.array([x])
def evolve2d(cellular_automaton, timesteps, apply_rule, r=1, neighbourhood='Moore'):
_, rows, cols = cellular_automaton.shape
array = np.zeros((timesteps, rows, cols), dtype=cellular_automaton.dtype)
array[0] = cellular_automaton
von_neumann_mask = np.zeros((2*r + 1, 2*r + 1), dtype=bool)
for i in range(len(von_neumann_mask)):
mask_size = np.absolute(r - i)
von_neumann_mask[i][:mask_size] = 1
if mask_size != 0:
von_neumann_mask[i][-mask_size:] = 1
def get_neighbourhood(cell_layer, row, col):
row_indices = [0]*(2*r+1)
for i in range(-r,r+1):
row_indices[i+r]=(i+row) % cell_layer.shape[0]
col_indices = [0]*(2*r+1)
for i in range(-r,r+1):
col_indices[i+r]=(i+col) % cell_layer.shape[1]
n = cell_layer[np.ix_(row_indices, col_indices)]
if neighbourhood == 'Moore':
return n
elif neighbourhood == 'von Neumann':
return np.ma.masked_array(n, von_neumann_mask)
else:
raise Exception("unknown neighbourhood type: %s" % neighbourhood)
for t in range(1, timesteps):
cell_layer = array[t - 1]
for row, cell_row in enumerate(cell_layer):
for col, cell in enumerate(cell_row):
n = get_neighbourhood(cell_layer, row, col)
array[t][row][col] = apply_rule(n, (row, col), t)
return array
def ca_reaction_diffusion(neighbourhood, c, t):
center_cell = neighbourhood[1][1]
total = np.sum(neighbourhood==1)
if total >= theta and center_cell==0:
return 1
elif center_cell == 1:
return 2
elif center_cell == 2:
return 3
elif center_cell == 3:
return 0
else:
return 0
# Initial condition
cellular_automaton = init_simple2d(size, size, val=0, dtype=int)
# Excitable initial cells
cellular_automaton[:, [1,2], [1,1]] = 1
# The evolution
cellular_automaton = evolve2d(cellular_automaton,
timesteps=time_steps,
neighbourhood='Moore',
apply_rule=ca_reaction_diffusion)
animation=plot2d_animate(cellular_automaton)
Explanation of the code:
As you can see, there are 4 states: 0 (green), 1 (red), 2 (black) and 3 (gray). The way the automata evolves is with the cellular_automaton conditions. That is, for example, if a center cell has a value of 0 (excitable cell) and at least one cell (theta value) on its Moore neighbourhood is in state 1, in the following time step the same cell will be at state 1 (excited).
To notice:
The configuration of this matrix is toroidal, and the definitions are taken from the cellpylib library.
I've been stuck with this for over a week, so I'd really appreciate some help. Thanks in advance!
I am not well-experienced in this subject matter (and I was not fully clear on what you intended for me to do). I went through and implemented the counting of the specific "0", "1", "2" and "3" value cells in "evolve2d" function. This code should be viewed as "starter code"; whatever specifically you are trying to do should piggyback off of what I have given you. Additionally, this task could have been accomplished through some better code design and definitely, better planning of your function locations (as part of better coding practice and overall cleaner code that is easy to debug). Please peruse and UNDERSTAND the changes that I made.
#Libraries
import matplotlib
matplotlib.matplotlib_fname()
import matplotlib.pyplot as plt
import matplotlib as mpl
import matplotlib.animation as animation
import numpy as np
import csv
# Conditions
#############################
theta = 1 # this is the condition for Moore neighbourhood
iter_speed = 100 # this is the iteration speed (just for visualization)
time_steps = 100 # Iterations
size = 8 # this is the size of the matrix (8x8)
#############################
# Definitions
def plot2d_animate(ca, title=''):
c = mpl.colors.ListedColormap(['green', 'red', 'black', 'gray'])
n = mpl.colors.Normalize(vmin=0,vmax=3)
fig = plt.figure()
plt.title(title)
im = plt.imshow(ca[0], animated=True, cmap=c, norm=n)
i = {'index': 0}
def updatefig(*args):
i['index'] += 1
if i['index'] == len(ca):
i['index'] = 0
im.set_array(ca[i['index']])
return im,
ani = animation.FuncAnimation(fig, updatefig, interval=iter_speed, blit=True)
plt.show()
#############I ADDED EXTRA ARGUMENTs FOR THE FUNCTION BELOW
def get_neighbourhood(cell_layer, row, col, r = 1, neighbourhood = "Moore"):
row_indices = [0]*(2*r+1)
for i in range(-r,r+1):
row_indices[i+r]=(i+row) % cell_layer.shape[0]
col_indices = [0]*(2*r+1)
for i in range(-r,r+1):
col_indices[i+r]=(i+col) % cell_layer.shape[1]
n = cell_layer[np.ix_(row_indices, col_indices)]
if neighbourhood == 'Moore':
return n
elif neighbourhood == 'von Neumann':
return np.ma.masked_array(n, von_neumann_mask)
else:
raise Exception("unknown neighbourhood type: %s" % neighbourhood)
def init_simple2d(rows, cols, val=1, dtype=np.int):
x = np.zeros((rows, cols), dtype=dtype)
x[x.shape[0]//2][x.shape[1]//2] = val
return np.array([x])
#Inner functions was moved due to bad coding practice. Arguments were also changed. Make sure you understand what I did.
def evolve2d(cellular_automaton, timesteps, apply_rule, r=1, neighbourhood='Moore'):
_, rows, cols = cellular_automaton.shape
array = np.zeros((timesteps, rows, cols), dtype=cellular_automaton.dtype)
array[0] = cellular_automaton
von_neumann_mask = np.zeros((2*r + 1, 2*r + 1), dtype=bool)
for i in range(len(von_neumann_mask)):
mask_size = np.absolute(r - i)
von_neumann_mask[i][:mask_size] = 1
if mask_size != 0:
von_neumann_mask[i][-mask_size:] = 1
#################################################
#These lists keep track of values over the course of the function:
Result_0 = ["Number of 0"]
Result_1 = ["Number of 1"]
Result_2 = ["Number of 2"]
Result_3 = ["Number of 3"]
#################################################
for t in range(1, timesteps):
#################################################
#This dictionary keeps track of values per timestep
value_iter_tracker = {0: 0, 1: 0, 2: 0, 3: 0 }
#################################################
cell_layer = array[t - 1]
for row, cell_row in enumerate(cell_layer):
for col, cell in enumerate(cell_row):
n = get_neighbourhood(cell_layer, row, col)
################################################
res = apply_rule(n, (row, col), t)
value_iter_tracker[res]+=1
array[t][row][col] = res
################################################
print(value_iter_tracker)
########################################################
#Now we need to add the results of the iteration dictionary to the corresponding
#lists in order to eventually export to the csv
Result_0.append(value_iter_tracker[0])
Result_1.append(value_iter_tracker[1])
Result_2.append(value_iter_tracker[2])
Result_3.append(value_iter_tracker[3])
########################################################
############################################################
#function call to export lists to a csv:
timesteps_result = list(range(1, timesteps))
timesteps_result = ["Time Step"] + timesteps_result
#If you don't understand what is going on here, put print statement and/or read docs
vals = zip(timesteps_result, Result_0, Result_1, Result_2, Result_3)
write_to_csv_file(list(vals))
############################################################
return array
################################################################################
#THIS CODE IS FROM:
#https://stackoverflow.com/questions/14037540/writing-a-python-list-of-lists-to-a-csv-file
import pandas as pd
def write_to_csv_file(data):
data = [list(x) for x in data]
my_df = pd.DataFrame(data)
my_df.to_csv('output1.csv', index=False, header=False)
################################################################################
def ca_reaction_diffusion(neighbourhood, c, t):
center_cell = neighbourhood[1][1]
total = np.sum(neighbourhood==1)
if total >= theta and center_cell==0:
return 1
elif center_cell == 1:
return 2
elif center_cell == 2:
return 3
elif center_cell == 3:
return 0
else:
return 0
# Initial condition
cellular_automaton = init_simple2d(size, size, val=0, dtype=int)
# Excitable initial cells
cellular_automaton[:, [1,2], [1,1]] = 1
# The evolution
cellular_automaton = evolve2d(cellular_automaton,
timesteps=time_steps,
neighbourhood='Moore',
apply_rule=ca_reaction_diffusion)
animation=plot2d_animate(cellular_automaton)
I have left comments that should clarify the changes that I made. Essentially, when you call the evolve2d function, a csv file called "output1.csv" is created with the timestep results. I used the pandas package to write the data into a csv but other methods could have been used as well. I will leave it to you to take advantage of the changes that I made for your use. Hope this helps.

How do I iterate through data in a panda data frame?

I have created a 5 day moving average for 5 years worth of data. How do I iterate through this to show if the moving average is rising or falling for every single day. My code is simply giving me 1 integer answer rather than a rising (+1) or falling(-1) answer for every day. Thank you!
import pandas as pd
df = pd.read_csv('file:///C:/Users/James Brodie/Desktop/USDJPY.csv', header=1, index_col=0)
ma5 = df['PX_LAST'].rolling(window=5).mean()
ma8 = df['PX_LAST'].rolling(window=8).mean()
ma21 = df['PX_LAST'].rolling(window=21).mean()
ma5x = []
for i in ma5:
if i > i-1:
ma5x = 1
elif i < i-1:
ma5x = -1
else:
ma5x = 0
print(ma5x)
Thank you!
ma5 = [5,2,2,3,3,2,5]
ma5x = []
lastItem = ma5[0]
for currItem in ma5[1:]:
if currItem > lastItem:
ma5x.append(1)
elif currItem < lastItem:
ma5x.append(-1)
else:
ma5x.append(0)
lastItem = currItem
print(ma5x)
gives:
[-1, 0, 1, 0, -1, 1]
The elements of a list are best represented in pandas as a Series object (put own index of choice for rows replacing list(range(len(ma5x))) with anything you need):
print('-----------')
import pandas as pd
pd_ma5x = pd.Series(ma5x, index=list(range(len(ma5x))))
print(pd_ma5x)
gives:
-----------
0 -1
1 0
2 1
3 0
4 -1
5 1
dtype: int64
Using own index be aware that pd_ma5x size is one less than that of ma5

Resources