Hello everyone here is my code:
n =[[34,2,55,24,22],[31,22,4,7,333],[87,74,44,12,48]]
for r in n:
for c in r:
print(c,end = " ")
print()
sums=[]
for i in n:
sum=0
for num in i:
sum+=int(num)
sums.append(sum)
print(*sums)
print(*(min(row) for row in n))
And here is what it prints out:
34 2 55 24 22
31 22 4 7 333
87 74 44 12 48
137 397 265
2 4 12
I need to change row whith smallest number and bigest number so it means row 1 and 2 like this:
31 22 4 7 333
34 2 55 24 22
87 74 44 12 48
#end result needs to look like this:
34 2 55 24 22
31 22 4 7 333
87 74 44 12 48
137 397 265
2 4 12
31 22 4 7 333
34 2 55 24 22
87 74 44 12 48
Please help me i cant use numpy because it doesnt work I tried using it but all it gives are errors.
I assume you want the list with max at the first index and the one with the min at the end,
maxs = [max(i) for i in n]
mins = [min(i) for i in n]
max_idx = maxs.index(max(maxs))
min_idx = mins.index(min(mins))
n[max_idx], n[min_idx] = n[min_idx], n[max_idx]
# you need to think about when min_idx = max_idx
# or when there's more than one max/min
If you don't mind numpy, you can use:
max_idx = np.argmax(np.max(n, axis=1))
min_idx = np.argmin(np.min(n, axis=1))
Related
I am struggling in one of the Pattern matching problems in Python
When input = 3, below is the expected output (input value is the number of columns it should print)
Expected output:
1
2 6
3 7 9
4 8
5
I am somehow moving in a wrong direction, hence would need some help in it.
This is the code I have tried so far:
def display():
n = 5
i = 1
# Outer loop for how many lines we want to print
while(i<=n):
k = i
j = 1
# Inner loop for printing natural number
while(j <= i):
print (k,end=" ")
# Logic to print natural value column-wise
k = k + n - j
j = j + 1
print("\r")
i = i + 1
#Driver code
display()
But it is giving me output as this:
1
2 6
3 7 10
4 8 11 13
5 9 12 14 15
Anybody who can help me with this?
n=10
for i in range(1,2*n):
k=i
for j in range(2*n-i if i>n else i):
print(k,end=' ')
k = k + 2*n - 2*j - 2
print()
Result
1
2 20
3 21 37
4 22 38 52
5 23 39 53 65
6 24 40 54 66 76
7 25 41 55 67 77 85
8 26 42 56 68 78 86 92
9 27 43 57 69 79 87 93 97
10 28 44 58 70 80 88 94 98 100
11 29 45 59 71 81 89 95 99
12 30 46 60 72 82 90 96
13 31 47 61 73 83 91
14 32 48 62 74 84
15 33 49 63 75
16 34 50 64
17 35 51
18 36
19
>
Here's a way, I started from scratch and not for code, much more easy for me
def build(nb_cols):
values = list(range(1, nb_cols ** 2 + 1))
res = []
for idx in range(nb_cols):
row_values, values = values[-(idx * 2 + 1):], values[:-(idx * 2 + 1)]
res.append([' '] * (nb_cols - idx - 1) + row_values + [' '] * (nb_cols - idx - 1))
for r in zip(*reversed(res)):
print(" ".join(map(str, r)))
Here's a recursive solution:
def col_counter(start, end):
yield start
if start < end:
yield from col_counter(start+1, end)
yield start
def row_generator(start, col, N, i=1):
if i < col:
start = start + 2*(N - i)
yield start
yield from row_generator(start, col, N, i+1)
def display(N):
for i, col_num in enumerate(col_counter(1, N), 1):
print(i, *row_generator(i, col_num, N))
Output:
>>> display(3)
1
2 6
3 7 9
4 8
5
>>> display(4)
1
2 8
3 9 13
4 10 14 16
5 11 15
6 12
7
>>> display(10)
1
2 20
3 21 37
4 22 38 52
5 23 39 53 65
6 24 40 54 66 76
7 25 41 55 67 77 85
8 26 42 56 68 78 86 92
9 27 43 57 69 79 87 93 97
10 28 44 58 70 80 88 94 98 100
11 29 45 59 71 81 89 95 99
12 30 46 60 72 82 90 96
13 31 47 61 73 83 91
14 32 48 62 74 84
15 33 49 63 75
16 34 50 64
17 35 51
18 36
19
Here is the solution using simple loops
def display(n):
nrow = 2*n -1 #Number of rows
i = 1
noofcols = 1 #Number of columns in each row
t = 1
while (i <= nrow):
print(i,end=' ')
if i <= n:
noofcols = i
else:
noofcols = 2*n - i
m =i
if t < noofcols:
for x in range(1,noofcols):
m = nrow + m -(2*x-1)
print(m, end=' ')
i = i+1
print()
I have the following dataset:
ID Length Width Range_CAP Capacity_CAP
0 1 33 25 16 50
1 2 34 22 11 66
2 3 22 12 15 42
3 4 46 45 66 54
4 5 16 6 23 75
5 6 21 42 433 50
I basically want to sum the row values of the columns only where the columns match a string (in this case, all columns with _CAP at the end of their name). And store the sum of the result in a new column.
So that I end up with a dataframe that looks something like this:
ID Length Width Range_CAP Capacity_CAP CAP_SUM
0 1 33 25 16 50 66
1 2 34 22 11 66 77
2 3 22 12 15 42 57
3 4 46 45 66 54 120
4 5 16 6 23 75 98
5 6 21 42 433 50 483
I first tried to use the solution recommended in this question here:
Summing columns in Dataframe that have matching column headers
However, the solution doesn't work for me since they are summing up columns that have the same exact name so a simple groupby can accomplish the result whereas I am trying to sum columns with specific string matches only.
Code to recreate above sample dataset:
data1 = [['1', 33,25,16,50], ['2', 34,22,11,66],
['3', 22,12,15,42],['4', 46,45,66,54],
['5',16,6,23,75], ['6', 21,42,433,50]]
df = pd.DataFrame(data1, columns = ['ID', 'Length','Width','Range_CAP','Capacity_CAP'])
Let us do filter
df['CAP_SUM'] = df.filter(like='CAP').sum(1)
Out[86]:
0 66
1 77
2 57
3 120
4 98
5 483
dtype: int64
If have other CAP in front
df.filter(regex='_CAP$').sum(1)
Out[92]:
0 66
1 77
2 57
3 120
4 98
5 483
dtype: int64
One approach is:
df['CAP_SUM'] = df.loc[:, df.columns.str.endswith('_CAP')].sum(1)
print(df)
Output
ID Length Width Range_CAP Capacity_CAP CAP_SUM
0 1 33 25 16 50 66
1 2 34 22 11 66 77
2 3 22 12 15 42 57
3 4 46 45 66 54 120
4 5 16 6 23 75 98
5 6 21 42 433 50 483
The expression:
df.columns.str.endswith('_CAP')
creates a boolean mask where the values are True if and only if the column name ends with CAP. As an alternative use filter, with the following regex:
df['CAP_SUM'] = df.filter(regex='_CAP$').sum(1)
print(df)
Output (of filter)
ID Length Width Range_CAP Capacity_CAP CAP_SUM
0 1 33 25 16 50 66
1 2 34 22 11 66 77
2 3 22 12 15 42 57
3 4 46 45 66 54 120
4 5 16 6 23 75 98
5 6 21 42 433 50 483
You may try this:
columnstxt = df.columns
df['sum'] = 0
for i in columnstxt:
if i.find('_CAP') != -1:
df['sum'] = df['sum'] + df[i]
else:
pass
Here, in my code, the correlation matrix is a dataframe and diag is a list.
When I run the following code (CholDC part at the bottom), it returns numpy.float64 object is not iterable.
What do I need to do to make this code work?
def CholDC (correl, diag):
for column in correl:
j = 0
for j in correl[str(column)][j]:
Sum = correl[str(column)][j]
k = int(column)-1
if k >= 1:
Sum = Sum - correl[str(column)][k]*correl[str(j)][k]
else:
Sum = Sum
if int(column) == j:
if Sum <= 0:
print ("Should be PSD")
else:
diag[int(column)] = np.sqrt(Sum)
else:
correl[str(j)][int(column)] = Sum / diag[int(column)]
diag = []
df_correl = pd.DataFrame(df_correlation)
CholDC(df_correl, diag)
To loop through a dataframe, you need to use iterrows(). See the example below:
import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.randint(0,100, size=(10, 4)), columns=list('ABCD'))
print(df)
for index, row in df.iterrows():
print(row['B'], row['C'])
#dataframe output
A B C D
0 53 60 63 44
1 17 12 20 55
2 85 28 76 99
3 39 75 69 30
4 2 85 21 3
5 22 5 45 33
6 78 65 22 38
7 14 99 0 67
8 18 70 53 19
9 54 25 96 7
#output from loop
60 63
12 20
28 76
75 69
85 21
5 45
65 22
99 0
70 53
25 96
So use iterrows() in your code instead of for column in correl.
If we have the following data:
X = pd.DataFrame({"t":[1,2,3,4,5],"A":[34,12,78,84,26], "B":[54,87,35,25,82], "C":[56,78,0,14,13], "D":[0,23,72,56,14], "E":[78,12,31,0,34]})
X
A B C D E t
0 34 54 56 0 78 1
1 12 87 78 23 12 2
2 78 35 0 72 31 3
3 84 25 14 56 0 4
4 26 82 13 14 34 5
How can I shift the data in a cyclical fashion so that the next step is:
A B C D E t
4 26 82 13 14 34 5
0 34 54 56 0 78 1
1 12 87 78 23 12 2
2 78 35 0 72 31 3
3 84 25 14 56 0 4
And then:
A B C D E t
3 84 25 14 56 0 4
4 26 82 13 14 34 5
0 34 54 56 0 78 1
1 12 87 78 23 12 2
2 78 35 0 72 31 3
etc.
This should also shift the index values with the row.
I know of pandas X.shift(), but it wasn't making the cyclical thing.
You can combine reindex with np.roll:
X = X.reindex(np.roll(X.index, 1))
Another option is to combine concat with iloc:
shift = 1
X = pd.concat([X.iloc[-shift:], X.iloc[:-shift]])
The resulting output:
A B C D E t
4 26 82 13 14 34 5
0 34 54 56 0 78 1
1 12 87 78 23 12 2
2 78 35 0 72 31 3
3 84 25 14 56 0 4
Timings
Using the following setup to produce a larger DataFrame and functions for timing:
df = pd.concat([X]*10**5, ignore_index=True)
def root1(df, shift):
return df.reindex(np.roll(df.index, shift))
def root2(df, shift):
return pd.concat([df.iloc[-shift:], df.iloc[:-shift]])
def ed_chum(df, num):
return pd.DataFrame(np.roll(df, num, axis=0), np.roll(df.index, num), columns=df.columns)
def divakar1(df, shift):
return df.iloc[np.roll(np.arange(df.shape[0]), shift)]
def divakar2(df, shift):
idx = np.mod(np.arange(df.shape[0])-1,df.shape[0])
for _ in range(shift):
df = df.iloc[idx]
return df
I get the following timings:
%timeit root1(df.copy(), 25)
10 loops, best of 3: 61.3 ms per loop
%timeit root2(df.copy(), 25)
10 loops, best of 3: 26.4 ms per loop
%timeit ed_chum(df.copy(), 25)
10 loops, best of 3: 28.3 ms per loop
%timeit divakar1(df.copy(), 25)
10 loops, best of 3: 177 ms per loop
%timeit divakar2(df.copy(), 25)
1 loop, best of 3: 4.18 s per loop
You can use np.roll in a custom func:
In [83]:
def roll(df, num):
return pd.DataFrame(np.roll(df,num,axis=0), np.roll(df.index, num), columns=df.columns)
roll(X,1)
Out[83]:
A B C D E t
4 26 82 13 14 34 5
0 34 54 56 0 78 1
1 12 87 78 23 12 2
2 78 35 0 72 31 3
3 84 25 14 56 0 4
In [84]:
roll(X,2)
Out[84]:
A B C D E t
3 84 25 14 56 0 4
4 26 82 13 14 34 5
0 34 54 56 0 78 1
1 12 87 78 23 12 2
2 78 35 0 72 31 3
Here we return a df using the rolled df array, with the index rolled also
You can use numpy.roll :
import numpy as np
nb_iterations = 3 # number of steps you want
for i in range(nb_iterations):
for col in X.columns :
df[col] = numpy.roll(df[col], 1)
Which is equivalent to :
for col in X.columns :
df[col] = numpy.roll(df[col], nb_iterations)
Here is a link to the documentation of this useful function.
One approach would be creating such an shifted-down indexing array once and re-using it over and over to index into rows with .iloc, like so -
idx = np.mod(np.arange(X.shape[0])-1,X.shape[0])
X = X.iloc[idx]
Another way to create idx would be with np.roll : np.roll(np.arange(X.shape[0]),1).
Sample run -
In [113]: X # Starting version
Out[113]:
A B C D E t
0 34 54 56 0 78 1
1 12 87 78 23 12 2
2 78 35 0 72 31 3
3 84 25 14 56 0 4
4 26 82 13 14 34 5
In [114]: idx = np.mod(np.arange(X.shape[0])-1,X.shape[0]) # Creating once
In [115]: X = X.iloc[idx] # Using idx
In [116]: X
Out[116]:
A B C D E t
4 26 82 13 14 34 5
0 34 54 56 0 78 1
1 12 87 78 23 12 2
2 78 35 0 72 31 3
3 84 25 14 56 0 4
In [117]: X = X.iloc[idx] # Re-using idx
In [118]: X
Out[118]:
A B C D E t
3 84 25 14 56 0 4
4 26 82 13 14 34 5
0 34 54 56 0 78 1
1 12 87 78 23 12 2
2 78 35 0 72 31 3 ## and so on
I have to make a times table code using recursive functions. I have to ask the user for a number and print out the times tables from 1 to 12. And I have to use recursive functions and it is not allowed to use for loops or while loops and all variables besides the user input have to be defined inside the functions. I am having trouble defining the number that the user provided number needs to be multiplied with. E.X. 2 x 1 2 x 2 2 x 3.
def times_tables(num):
def multiply(x):
product = x * num
if x < 12:
print (str(multiply(x + 1)))
user = input("Enter a number: ")
times_tables(user)
If I define x in the times_tables function then every time the function runs it will get set back to whatever I set it to the first time. Thanks for your help.
You are not modifying x, x is passed by value, this mean it is copied.
If you want to keep the exit conditon outside the recursion you need a way to write X directly from the recursion, which probably would involve a global (bad practices so avoid).
You need to have the exit condition inside multiply, because that will be your recursion, in that case your X will increase and you will do the check on the proper incremented value. Or change the function all together as ruggfrancesco suggested
def times_tables(n, t=1):
if t == 13:
return
print(str(n) + " x " + str(t) + " = " + str(n*t))
times_tables(n, t+1)
times_tables(int(input("Enter number: ")))
Enter number: 3
3 x 1 = 3
3 x 2 = 6
3 x 3 = 9
3 x 4 = 12
3 x 5 = 15
3 x 6 = 18
3 x 7 = 21
3 x 8 = 24
3 x 9 = 27
3 x 10 = 30
3 x 11 = 33
3 x 12 = 36
When I (Image) Google "times table", I get a very different result from what the other answers produce. Below is my recursive solution in two dimensions:
def times_table(limit):
number_format = "{{:{}}}".format(len(str(limit ** 2)))
def times_table_recursive(number, increment):
minimum = max(increment, 1)
if number <= minimum * limit:
print(number_format.format(number if number > 0 else 'x'), end=' ')
times_table_recursive(number + minimum, increment)
elif increment < limit:
print()
increment += 1
print(number_format.format(increment), end=' ')
times_table_recursive(increment, increment)
else:
print()
times_table_recursive(0, 0)
times_table(12)
OUTPUT
> python3 test.py
x 1 2 3 4 5 6 7 8 9 10 11 12
1 1 2 3 4 5 6 7 8 9 10 11 12
2 2 4 6 8 10 12 14 16 18 20 22 24
3 3 6 9 12 15 18 21 24 27 30 33 36
4 4 8 12 16 20 24 28 32 36 40 44 48
5 5 10 15 20 25 30 35 40 45 50 55 60
6 6 12 18 24 30 36 42 48 54 60 66 72
7 7 14 21 28 35 42 49 56 63 70 77 84
8 8 16 24 32 40 48 56 64 72 80 88 96
9 9 18 27 36 45 54 63 72 81 90 99 108
10 10 20 30 40 50 60 70 80 90 100 110 120
11 11 22 33 44 55 66 77 88 99 110 121 132
12 12 24 36 48 60 72 84 96 108 120 132 144
>
Only goes up to times_table(30) without expanding Python's recursion depth limit.
def fun (no,i=1):
if i==10:
print (no*i)
else:
print (no*fun(i+1)
no=int (input ("Enter a no="))
fun (no)