Trying to check if tuple item is nan - python

I have the below for loop and am try to check first if the tuple(row) item in position 10 is Nan
i=0
for row in df.iterrows():
if row[1][10] != None:
names = row[1][10].split(',')
for name in names:
df2.loc[i,:] = row[1][:]
i=i+1
else:
i=i+1
I thought I could use if row[1][10] != None: but it doesnt seem to work, anyone know the solution?

Can use pd.isnull(row[1][10]) instead of if row[1][10] != None.
Example:
i=0
for row in df.iterrows():
if pd.isnull(row[1][10]):
df2.loc[i,:] = row[1][:]
i=i+1
else:
names = row[1][10].split(',')
for name in names:
df2.loc[i,:] = row[1][:]
df2.loc[i,'name'] = name
i=i+1
Also please do give feedback about this solution.

Related

How to change value in one cell to value in another (pandas)

I am trying to create some lag features by subtracting a month from each date in my datetime column and then assigning a column value from the past date to the current one.
This is my code:
for row_index in range(0,len(merger)):
date = merger.loc[merger.index[row_index],'datetime']
prev = subtract_one_month(date)
inde = merger.loc[merger['datetime'] == str(prev),'count'].index.values.astype(int)
if inde == []:
continue
else:
inde = inde[0]
merger.loc[merger.index[row_index], 'count_lag_month'] =
merger.loc[merger.index[inde], 'count']
The inner if else loop is meant to deal with cases where the date I'm looking for doesn't exist.
The code above simply gives me a list of NaNs. I would appreciate any help.
I've changed my
first = []
mean = []
wrkday = []
count = []
for row_index in range(0,len(merger)):
print(row_index)
date = merger.loc[merger.index[row_index],'datetime']
prev = subtract_one_month(date)
inde = merger.loc[merger['datetime'] == str(prev)].index.values.astype(int)
if inde.size == 0:
first.append(0)
mean.append(0)
wrkday.append(0)
continue
else:
inde = inde[0]
first.append(merger.loc[merger.index[inde], 'count'])
mean.append(merger.loc[merger.index[inde], 'monthly_mean_count'])
wrkday.append(merger.loc[merger.index[inde], 'monthly_wrkday_mean_count'])
prev_day = subtract_one_day(date)
inde = merger.loc[merger['datetime'] == str(prev_day)].index.values.astype(int)
if inde.size == 0:
count.append(0)
continue
else:
inde = inde[0]
count.append(merger.loc[merger.index[inde], 'count'])
merger['count_lag_month'] = first
merger['monthly_mean_count_lag_month'] = mean
merger['monthly_wrkday_mean_count_lag_month'] = wrkday
merger['count_lag_day'] = count
It uses lists instead and it seems to run at a decent speed. I'm not sure if it's the best approach though.

Efficiently update columns based on one of the columns split value

So here is my code updating many column values based on a condition of split values of the column 'location'. The code works fine, but as its iterating by row it's not efficient enough. Can anyone help me to make this code work faster please?
for index, row in df.iterrows():
print index
location_split =row['location'].split(':')
after_county=False
after_province=False
for l in location_split:
if l.strip().endswith('ED'):
df[index, 'electoral_district'] = l
elif l.strip().startswith('County'):
df[index, 'county'] = l
after_county = True
elif after_province ==True:
if l.strip()!='Ireland':
df[index, 'dublin_postal_district'] = l
elif after_county==True:
df[index, 'province'] = l.strip()
after_province = True
'map' was what I needed :)
def fill_county(column):
res = ''
location_split = column.split(':')
for l in location_split:
if l.strip().startswith('County'):
res= l.strip()
break
return res
df['county'] = map(fill_county, df['location'])

Python - Finding next element in list matching a condition. Substitute previous entry

I have a list of elements to which I inputted some "identifiable" values that are not to go to my database. I want to find and substitute those values. Code looks like this (tried to be generic and illustrative, the date and time is predefined vars):
A = []
A.append(['Name1',date1,time1,0.00])
A.append(['Name1',date1,time2,0.00])
A.append(['Name2',date1,time1,price1])
A.append(['Name1',date1,time3,price2])
A.append(['Name1',date1,time4,price3])
A.append(['Name1',date2,time5,price4])
and so on. This 0.00 price should be changed by the next price where we have 'Name1' in position 0 and date1 in position 1, i.e.:
print(A[0])
print(A[1])
should yield
['Name1',date1,time1,price1]
['Name1',date1,time2,price1]
Appreciate your help.
Try this code for printing, pass the list and index for the same.
def print1(lists, index):
if lists[index][3] == 0:
try:
name=lists[index][0]
val = next(l[3] for l in lists[index:] if l[3]>0 and l[0]==name)
print lists[index][:-1] + [val]
except:
print "No value found with same name where price>0"
else:
print lists[index]
A=[]
A.append(['Name1','date1','time1',0.00])
A.append(['Name1','date1','time2',0.00])
A.append(['Name2','date1','time1',10])
A.append(['Name1','date1','time3',20])
A.append(['Name1','date1','time4',30])
A.append(['Name1','date2','time5',40])
print1(A,1)
you can return the values in place of printing them in case you need them to.
May be you need a method like this:
A = []
def insert_or_update_by_name_and_date(x):
if not isinstance(x, list) or len(x) < 2:
return
for element in A:
if len(element) < 2:
continue
if element[0] == x[0] and element[1] == x[1]:
element[2] = x[2]
element[3] = x[3]
return
A.append(x)
You can use two for loops:
for i in range(len(A)):
for j in range(i, len(A)):
if A[i][3] == 0.0 and A[j]]0] == 'Name1' and A[j][1] == date1:
A[i][3] = A[j][3]
Apart from that, you may find this discussion on when to use a Dictionary, List or Set useful.

why this source code is "List index out of range"

i try to create this soure code and show message "List index out of range "
def main():
pass
data = [1,2,3,4,5]
temp = data[0]
i = 0
n = len(data)
while i<n:
data[i]=data[i+1]
i+=1
print data
if __name__ == '__main__':
main()
please help me to fixed this source code
Basically, you can solve this by changing the while i<n to while i<n-1.
But better yet, change:
i = 0
n = len(data)
while i<n:
data[i]=data[i+1]
i+=1
To:
n = len(data)
for i in range(0,n-1):
data[i] = data[i+1]
data[n-1] = ... # Whatever you want to set the last entry to
And if all you want to do is removing the first element, then simply use:
temp = data.pop(0)
print data
In the last iteration of while loop, the statement data[i+1] tries to access the non existing index i+1 of the list data.
If the value of i is 4, then, data[i+1] refers to the fifth index, which is not defined

python xlrd string match

I couldnt find anything in the API. Is there a way to return the row number or coordinate of a cell based on a string match? For instance: You give the script a string and it scans through the .xls file and when it finds a cell with the matching string, it returns the coordinate or row number.
for i in range(sheet.nrows):
row = sheet.row_values(i)
for j in range(len(row)):
if row[j] == search_value:
return i,j
return None
something like that... just a basic search
You could try the following function, thank you Joran
def look4_xlrd (search_value, sheet) :
lines = []
columns = []
for i in range (sheet.nrows) :
row = sheet.row_values(i)
for j in range(len(row)) :
if row[j] == search_value :
lines.append(i)
columns.append(j)
del row
return lines, columns

Categories