Print list-matrix combination - python

I am trying to print a combination of np.array values, a string and and some values I get from an iterator.
The code looks like this:
import numpy as np
site = np.genfromtxt('.....\Plot_1.txt', dtype=None, delimiter='\t')
c1 = np.array([148, 108])
c2 = np.array([181, 147])
c3 = np.array([173, 153])
c4 = np.array([98, 221])
c5 = np.array([43, 153])
trees_list = [c1, c2, c3, c4, c5]
def trees_pixel(rc_list, matrix):
t_row = rc_list[0]
t_col = rc_list[1]
tree = matrix[t_row, t_col]
for i in range(1, 6, 1):
print "C",i,"=",tree
return tree
for i in trees_list:
trees_pixel(i, site)
Site is a np.array of 400x370 row/columns, that I need to read the values from. C1...C5 are the locations (row/column) from the 'site' array.
My code prints the following:
C 1 = 8.266602
C 2 = 8.266602
C 3 = 8.266602
C 4 = 8.266602
C 5 = 8.266602
C 1 = 17.89282
C 2 = 17.89282
C 3 = 17.89282
C 4 = 17.89282
C 5 = 17.89282
C 1 = 18.31433
C 2 = 18.31433
C 3 = 18.31433
C 4 = 18.31433
C 5 = 18.31433
etc...
But what I expected was:
C 1 = 8.266602
C 2 = 17.89282
C 3 = 18.31433
C 4 = 20.47229
C 5 = 13.5907
How can I do this, so I will avoid the repeating pattern? Thanks!

You're iterating twice, once inside trees_pixel and once outside of it. If I understand what you mean, you want something that looks like the following:
import numpy as np
site = np.random.random((400, 370)) # Used in place of your data
c1 = np.array([148, 108])
c2 = np.array([181, 147])
c3 = np.array([173, 153])
c4 = np.array([98, 221])
c5 = np.array([43, 153])
trees_list = [c1, c2, c3, c4, c5]
def trees_pixel(rc_list, listIdx, matrix):
t_row = rc_list[0]
t_col = rc_list[1]
tree = matrix[t_row, t_col]
print "C",listIdx,"=",tree
return tree
for i in xrange(len(trees_list)):
trees_pixel(trees_list[i], i+1, site)
C 1 = 0.820317259854
C 2 = 0.960883528796
C 3 = 0.363985436225
C 4 = 0.189575015844
C 5 = 0.667578060856

Related

Negative values with GCD python program

Iam doing GCD tool in python but for some reason every time I use 2 negative values I get back negative value back. Beceause this is for school i cant use things like obs() ort math etc.. Can some help me with that?
from sys import stdin
a = 0
b = 0
a0 = 0
b0 = 0
a1 = 0
b1 = 0
n = 0
na = 0
nb = 0
q = 0
for line in stdin:
input = line.lstrip().rstrip().split()
if line == '' or len(input) != 2:
break
a, b = [int(x) for x in line.lstrip().rstrip().split()]
if a > b:
a, b = b, a
#
# a | b
# +---------+
# a | 1 | 0 | "( a0, b0 )"
# b | 0 | 1 | "( a1, b1 )"
# n | na | nb | q
# | | |
#
#
a0 = 1
b0 = 0
a1 = 0
b1 = 1
n = a % b
q = a / b
na = a0 - q * a1
nb = b0 - q * b1
a = b
a0 = a1
b0 = b1
b = n
a1 = na
b1 = nb
while n != 0:
n = a % b
q = a // b
na = a0 + q * a1
nb = b0 + q * b1
a = b
a0 = a1
b0 = b1
b = n
a1 = na
b1 = nb
print(a)
I tried messing around with operators. I expect to -888 -2 be 2 not -2 (I need to fix the code not to edit results )
Edit 1 : Here are some examples of what i need
Input Output
7 11 1
888 2 2
905 5 5
-7 11 1
-888 -2 2
905 -5 5

How to get re-arrange the pandas dataframe based on frequency?

I have a dataframe like this:
import numpy as np
import pandas as pd
from collections import Counter
df = pd.DataFrame({'c0': ['app','e','i','owl','u'],'c1': ['p','app','i','g',''],'c2': ['g','p','app','owl','']})
df
c0 c1 c2
0 app p g
1 e app p
2 i i app
3 owl g owl
4 u
I would like to align the rows based on frequency of items.
Required dataframe with quantities:
c0 c1 c2
0 app app app
1 i i
2 owl owl
3 e p p
4 u g g
My attempt
all_cols = df.values.flatten()
all_cols = [i for i in all_cols if i]
freq = Counter(all_cols)
freq
I can get you this far:
import pandas as pd
df = pd.DataFrame({'c0': list('aeiou'),'c1': ['p','a','i','g',''],'c2': ['g','p','a','o','']})
allLetters = set(x for x in df.to_numpy().flatten() if x)
binaryIncidence = []
for letter in allLetters:
binaryIncidence.append(tuple(int(letter in df[col].tolist()) for col in df.columns))
x = list(zip(allLetters, binaryIncidence))
x.sort(key=lambda y:(y[1], -ord(y[0])), reverse=True)
x = [[y[0] if b else '' for b in y[1]] for y in x]
df_results = pd.DataFrame(x, columns=df.columns)
print(df_results)
... with this output:
c0 c1 c2
0 a a a
1 i i
2 o o
3 e
4 u
5 g g
6 p p
However, in the sample output from your question, you show 'e' getting paired up with 'p', 'p', and also 'u' getting paired up with 'g', 'g'. It's not clear to me how this selection would be made.
UPDATE: generalize to strings of arbitrary length
This will work not just with strings of length <=1 but of arbitrary length:
import pandas as pd
df = pd.DataFrame({'c0': ['app','e','i','owl','u'],'c1': ['p','app','i','g',''],'c2': ['g','p','app','owl','']})
allStrings = set(x for x in df.to_numpy().flatten() if x)
binaryIncidence = []
for s in allStrings:
binaryIncidence.append(tuple(int(s in df[col].tolist()) for col in df.columns))
x = list(zip(allStrings, binaryIncidence))
x.sort(key=lambda y:(tuple(-b for b in y[1]), y[0]))
x = [[y[0] if b else '' for b in y[1]] for y in x]
df_results = pd.DataFrame(x, columns=df.columns)
print(df_results)
Output:
c0 c1 c2
0 app app app
1 i i
2 owl owl
3 e
4 u
5 g g
6 p p

Compare Excel cells Python

I would like to compare two parts of two different columns from an Excel file that have a different number of elements. The comparison should be made between a part of Column 3 and a part of Column 2. Column 3 part has a length of j elements and Column 2 has a length of k elements(k>j). Column 2 part starts from row "j+1" and column 3 part starts from row 1. If an element from column 3 part is matching an element from column 2 part, then should check if the element from column1, before the j row, which has the same index as matched item from column 3 part is matching with the element from Column 1 part between j+1 and k, which has the same index as matched item from column 2 part. If yes, then should be written the element from Column 4 with the same index as matched element from column 2 part in a new Excel sheet.
Example: Column3[1]==Column2[2](which represents element 'A') => Column1[1]==Column1[j+2](which represents element 'P') => Column4[j+2] should be written in a new sheet.
Column 1 Column 2 Column 3 Column 4
P F A S
B G X T
C H K V
D I M W
P B R B
P A R D
C D H E
D E J k
E M K W
F F L Q
Q F K Q
For reading the Excel sheet cells from original sheet, I have used the df27.ix[:j-1,1].
One part of the code which reads the values of the mention part from column 3 and column 2 might be:
for j in range(1,j):
c3=sheet['B'+str(j)].value
for k in range(j,j+k):
c2=sheet['B'+str(k)].value
Any hint how I can accomplish this?
UPDATED
I have tried a new code which takes in consideration that we have '-', like joaquin mentioned in his example.
Joaquin's example:
C1 C2 C3 C4
0 P - A -
1 B - X -
2 C - K -
3 D - M -
4 P B - B
5 P A - D
6 C D - E
7 D E - k
8 E M - W
9 F F - Q
10 Q F - Q
New code:
from pandas import DataFrame as df
import pandas as pd
import openpyxl
wb=openpyxl.load_workbook('/media/sf_vboxshared/x.xlsx')
sheet=wb.get_sheet_by_name('Sheet1')
C13=[]
C12=[]
C1=[]
C2=[]
C3=[]
for s in range(2, sheet.max_row+1):
C1second=sheet['A'+str(s)].value
C2second=sheet['B'+str(s)].value
C3second=sheet['C'+str(s)].value
C1.append(C1second)
C2.append(C2second)
C3.append(C3second)
C1=[x.encode('UTF8') for x in C1]
for y in C2:
if y is not None:
C2=[x.encode('UTF8') if x is not None else None for x in C2]
for z in C3:
if z is not None:
C3=[x.encode('UTF8') if x is not None else None for x in C3]
for x in C1:
C13.append(x)
for x in C3:
C13.append(x)
for x in C1:
C12.append(x)
for x in C2:
C12.append(x)
tosave = pd.DataFrame()
df[C13]=pd.DataFrame(C13)
df[C12]=pd.DataFrame(C12)
for item in df[C13]:
if '-' in item: continue
new = df[df[C12] == item]
tosave = tosave.append(new)
But I still get the following error: df[C13]=pd.DataFrame(C13) TypeError: 'type' object does not support item assignment. Any idea what is wrong?
Many thanks in advance,
Dan
Given your df is
C1 C2 C3 C4
0 P - A -
1 B - X -
2 C - K -
3 D - M -
4 P B - B
5 P A - D
6 C D - E
7 D E - k
8 E M - W
9 F F - Q
10 Q F - Q
then, I combine C1 and C3 and C1 and C2
df['C13'] = df.apply(lambda x: x['C1'] + x['C3'], axis=1)
df['C12'] = df.apply(lambda x: x['C1'] + x['C2'], axis=1)
and compare which rows have the same pair of characters in columns C13 and C12, and save them in tosave
tosave = p.DataFrame()
for item in df['C13']:
if '-' in item: continue
new = df[df['C12'] == item]
tosave = tosave.append(new)
this gives you a tosave dataframe with the rows matching:
C1 C2 C3 C4 C13 C12
5 P A - D P- PA
That can be directly saved as it is or you can save just column C4
UPDATE: If you have data on each row, then you can not use the '-' detection (or any other kind of detection based on the differences between empty and filled columns). On the other hand, if j,k are not defined (for any j and k), your problem is actually reduced to find, for each row, identical pairs below that row. In consecuence, this:
tosave = p.DataFrame()
for idx, item in enumerate(df['C13']):
new = df[df['C12'] == item]
tosave = tosave.append(new.loc[idx+1:])
solves the problem given your labels and data is like:
C1 C2 C3 C4
0 P F A S
1 B G X T
2 C H K V
3 D I M W
4 P B R B
5 P A R D
6 C D H E
7 D E J k
8 E M K W
9 F F L Q
10 Q F K Q
This code also produces the same output as before:
C1 C2 C3 C4 C13 C12
5 P A R D PR PA
Note this probably needs some refinenment (p.e when a row produces 2 matches, the second row with produce 1 match, and you will need to remove replicates from the final output).

change table format of the output

I would like to change the format of my output for the following code.
import pandas as pd
x= pd.read_csv('x.csv')
y= pd.read_csv('y.csv')
z= pd.read_csv('z.csv')
list = pd.merge(x, y, how='left', on=['xx'])
list = pd.merge(list, z, how='left', on=['xx'])
columns_to_keep = ['yy','zz', 'uu']
list = list.set_index(['xx'])
list = list[columns_to_keep]
list = list.sort_index(axis=0, level=None, ascending=True, inplace=False,
sort_remaining=True, by=None)
with open('write.csv','w') as f:
list.to_csv(f,header=True, index=True, index_label='xx')
from this:
id date user_id user_name
1 8/13/2007 1 a1
2 1/8/2007 2 a2
2 1/8/2007 3 a3
3 12/14/2007 4 a4
4 3/6/2008 5 a5
4 4/14/2009 6 a6
4 5/30/2008 7 a7
4 5/30/2008 8 a8
5 6/17/2007 9 a9
to this:
id date user_id user_name
1 8/13/2007 1 a1
2 1/8/2007 2;3 a2;a3
3 12/14/2007 4 a4
4 3/6/2008 5;6;7;8 a5;a6;a7;a8
5 6/17/2007 9 a9
I think the following should work on the final dataframe (list), though I would suggest not to use "list" as a name as it is a built in function in python and you might want to use that function somewhere else. So in my code I will use "df" instead of "list":
ind = list(set(df.index.get_values()))
finaldf = pd.DataFrame(columns = list(df.columns))
for val in ind:
tempDF = df.loc[val]
print tempDF
for i in range(tempDF.shape[0]):
for jloc,j in enumerate(list(df.columns)):
if i != 0 and j != 'date':
finaldf.loc[val,j] += (";"+str(tempDF.iloc[i,jloc]))
elif i == 0:
finaldf.loc[val,j] = str(tempDF.iloc[i,jloc])
print finaldf

Printing two values using Runge Kutta Method

I am trying to print b and c from this code, but I am not having any luck. If I am correct, this code should output several points with a step size of 0.05, but I am not seeing it. Does anyone know how to print two values from this code?
import math
def rK3(a, b, c, fa, fb, fc, hs):
a1 = fa(a, b, c)*hs
b1 = fb(a, b, c)*hs
c1 = fc(a, b, c)*hs
ak = a + a1*0.5
bk = b + b1*0.5
ck = c + c1*0.5
a2 = fa(ak, bk, ck)*hs
b2 = fb(ak, bk, ck)*hs
c2 = fc(ak, bk, ck)*hs
ak = a + a2*0.5
bk = b + b2*0.5
ck = c + c2*0.5
a3 = fa(ak, bk, ck)*hs
b3 = fb(ak, bk, ck)*hs
c3 = fc(ak, bk, ck)*hs
ak = a + a3
bk = b + b3
ck = c + c3
a4 = fa(ak, bk, ck)*hs
b4 = fb(ak, bk, ck)*hs
c4 = fc(ak, bk, ck)*hs
a = a + (a1 + 2*(a2 + a3) + a4)/6
b = b + (b1 + 2*(b2 + b3) + b4)/6
c = c + (c1 + 2*(c2 + c3) + c4)/6
return a, b, c
def fa2(a, b, c):
return 0.9*(1 - b*b)*a - b + math.sin(c)
def fb2(a, b, c):
return a
def fc2(a, b, c):
return 0.5
def VDP2():
a, b, c, hs = 1, 1, 0, 0.05
while (c<6):
a, b, c = rK3(a, b, c, fa2, fb2, fc2, hs)
Your code does not have any print statement, so it will not print.
Try inserting something like:
print 'b = {0}, c = {1}'.format(b,c)
Where you want the print to happen. For Python 3 just add parentheses (print is a function now)
print('b = {0}, c = {1}'.format(b,c))

Categories

Resources