Taking an input as multiple elements instead of only 1 - python-2.7

I'm trying to create a function that will take the input of the user to create a 3x4 matrix, then find the sum of each column individually. But I'm not sure how to set up the input so that I'll be given each number individually instead of a long string.
def testMatrixFunctions():
row0 = input("Enter a 3-by-4 matrix row for row 0: ")
row1 = input("Enter a 3-by-4 matrix row for row 1: ")
row2 = input("Enter a 3-by-4 matrix row for row 2: ")
I could also use some help with adding the columns, but my biggest concern is the input at the moment.

Use the str.split() method:
>>> "1 2 3 4 5".split()
['1', '2', '3', '4', '5']
And then convert each string into an integer:
>>> map(int, "1 2 3 4 5".split())
[1, 2, 3, 4, 5]
>>> [int(c) for c in "1 2 3 4 5".split()]
[1, 2, 3, 4, 5]

Use split() function, which will split the input and you can 'eval' each element.
[eval(eachItem) for eachItem in inputList]
That will accept input regardless of the datatype.

Related

Putting a series of integers into a list in python

Is there any way to have an input of a series of random integers e.g. 1 2 3 4 and put them into a list e.g. [1, 2, 3, 4]
I have tried
a = [int(x) for x in input().split()]
and
a = map(int, input().split())
As DeepSpace commented, using raw_input() instead of input() solves your problem.
a = [int(x) for x in raw_input().split()]
Why? Because input() attempts to evaluate the input from raw_input(), which in this case is invalid (How can you evaluate '1 2 3 4').
I would suggest using this method to build your array
elements = []
for i in range(1, 5):
elements.append(i)

How to turn column of number into a list of strings?

I don't know why I cant figure this out. But I have a column of numbers that I would like to turn into a list of strings. I should of mention this when i initially posted this but this isn't a DataFrame or did it come from a file this is a result of a some code, sorry wasn't trying to waste anybody's time, I just didn't want to add a bunch of clutter. This is exactly how it prints out.
Here is my column of numbers.
3,1,3
3,1,3
3,1,3
3,3,3
3,1,1
And I would like them to look like this.
['3,1,3', '3,1,3', '3,1,3', '3,3,3', '3,1,1']
I'm trying to find a way that is not dependent on how many numbers are in each row or how many sets of numbers are in the column.
Thanks, really appreciate it.
Assume you start with a DataFrame
df = pd.DataFrame([[3, 1, 3], [3, 1, 3], [3, 1, 3], [3, 3, 3], [3, 1, 1]])
df.astype(str).apply(lambda x: ','.join(x.values), axis=1).values.tolist()
Looks like:
['3,1,3', '3,1,3', '3,1,3', '3,3,3', '3,1,1']
def foo():
l = []
with open("file.asd", "r") as f:
for line in f:
l.append(line)
return l
To turn your dataframe in to strings, use the astype function:
df = pd.DataFrame([[3, 1, 3], [3, 1, 3], [3, 1, 3], [3, 3, 3], [3, 1, 1]])
df = df.astype('str')
Then manipulating your columns becomes easy, you can for instance create a new column:
In [29]:
df['temp'] = df[0] + ',' + df[1] + ',' + df[2]
df
Out[29]:
0 1 2 temp
0 3 1 3 3,1,3
1 3 1 3 3,1,3
2 3 1 3 3,1,3
3 3 3 3 3,3,3
4 3 1 1 3,1,1
And then compact it into a list:
In [30]:
list(df['temp'])
Out[30]:
['3,1,3', '3,1,3', '3,1,3', '3,3,3', '3,1,1']
# Done in Jupyter notebook
# add three quotes on each side of your column.
# The advantage to dataframe is the minimal number of operations for
# reformatting your column of numbers or column of text strings into
# a single string
a = """3,1,3
3,1,3
3,1,3
3,3,3
3,1,1"""
b = f'"{a}"'
print('String created with triple quotes:')
print(b)
c = a.split('\n')
print ("Use split() function on the string. Split on newline character:")
print(c)
print ("Use splitlines() function on the string:")
print(a.splitlines())

how t find second greatest digit in a number ? Python

The Program must take a number and print the second largest digit in the number.
i have tried this ==>
a=raw_input("Please enter the nummber =")
l=list()
for i in a:
l.append(int(i))
great=0
for i in range(0,len(l)):
for j in l:
if l[i]>j:
if l[i]>great:
great=l[i]
print great
for i in range(20):
great-=1
for j in l:
if j==great:
print "Second largest number is ",j
break
But this gave Output
Please enter the nummber =1459
9
Second largest number is 5
Second largest number is 4
Second largest number is 1
this easily accomplished using the build-in function of python map and sorted
once you have the number from raw_input you can do this
>>> a
'1459'
>>> ordnum = sorted(map(int,a),reverse=True)
>>> ordnum[1]
5
>>> ordnum
[9, 5, 4, 1]
>>>
first with map convert every digit to a number, and result is passed to sorted that order them in ascending order by default, but with the reverse key-word argument the orden is reversed, then you get a list with the digit in order so the second elements is the desire digit.
Or as you already do the map part, you can do the sort part directly to the list
>>> l
[1, 4, 5, 9]
>>> l.sort(reverse=True)
>>> l
[9, 5, 4, 1]
>>>
to the same efect.
The problem with your code is that you don't break the first for-loop, only the second, to break both you can do as #cjahangir show, or make that into a function that return when find it like this
def second_great(great,num):
for i in range(10):
great -= 1
for j in num:
if j == great:
return j
and call it as
print great
print "Second largest number is ", second_great(great,l)
as pointed out by #Blckknght, the conversion to int is unneeded in this case because the digit are order correctly when handled individually, also you can use set to remove repetitions in any of the versions.
>>> b="1459934"
>>> sorted(b,reverse=True)
['9', '9', '5', '4', '4', '3', '1']
>>> sorted(set(b),reverse=True)
['9', '5', '4', '3', '1']
>>> sorted(map(int,set(b)),reverse=True)
[9, 5, 4, 3, 1]
>>>
I think this will work:
print great
flag = 0
for i in range(20):
great-=1
for j in l:
if j==great:
print "Second largest number is ",j
flag = 1
break
if flag:
break

Python: Write two lists into two column text file

Say I have two lists:
a=[1,2,3]
b=[4,5,6]
I want to write them into a text file such that I obtain a two column text file:
1 4
2 5
3 6
Simply zip the list, and write them to a csv file with tab as the delimiter:
>>> a=[1,2,3]
>>> b=[4,5,6]
>>> zip(a,b)
[(1, 4), (2, 5), (3, 6)]
>>> import csv
>>> with open('text.csv', 'w') as f:
... writer = csv.writer(f, delimiter='\t')
... writer.writerows(zip(a,b))
...
>>> quit()
$ cat text.csv
1 4
2 5
3 6
You can use numpy.savetxt(), which is a convenient tool from the numpy library.
A minimal example would be as follows:
import numpy as np
xarray = np.array([0, 1, 2, 3, 4, 5])
yarray = np.array([0, 10, 20, 30, 40, 50])
# here is your data, in two numpy arrays
data = np.column_stack([xarray, yarray])
datafile_path = "/your/data/output/directory/datafile.txt"
np.savetxt(datafile_path , data, fmt=['%d','%d'])
# here the ascii file is written.
The fmt field in np.savetxt() in the example specifies that the numbers are integers.
You can use a different format for each column.
E.g. to specify floating point format, with 2 decimal digits and 10 characters wide columns, you would use '%10.2f'.
Try this:
file = open("list.txt", "w")
for index in range(len(a)):
file.write(str(a[index]) + " " + str(b[index]) + "\n")
file.close()
A simple solution is to write columns of fixed-width text:
a=[1,2,3]
b=[4,5,6]
col_format = "{:<5}" * 2 + "\n" # 2 left-justfied columns with 5 character width
with open("foo.csv", 'w') as of:
for x in zip(a, b):
of.write(col_format.format(*x))
Then cat foo.csv produces:
1 4
2 5
3 6
The output is both human and machine readable, whereas tabs can generate messy looking output if the precision of the values varies along the column. It also avoids loading the separate csv and numpy libraries, but works with both lists and arrays.
You can write two lists into a text file that contains two columns.
a=[1,2,3]
b=[4,5,6]
c = [a, b]
with open("list1.txt", "w") as file:
for x in zip(*c):
file.write("{0}\t{1}\n".format(*x))
Output in the text file:
1 4
2 5
3 6
It exits a straightway to save and stack same vectors length in columns. To do so use the concatenate function, you can then stack 3,4 or N vectors in columns delimitered by a tab.
np.savetxt('experimental_data_%s_%.1fa_%dp.txt'%(signal,angle,p_range), np.c_[DCS_exp, p_exp], delimiter="\t")

Python Pandas replacing nan's in one column conditional on observations in another column

I have the following data frame in python pandas:
current_data = pd.DataFrame({'X': ['3'+'*NY', '3', '2', '2'+'*NY', '1', '7'], 'Y': [np.nan, 4, 5, np.nan, 8, np.nan]})
What I want to get is:
needed_data = pd.DataFrame({'X': ['3'+'*NY', '3', '2', '2'+'*NY', '1', '7'], 'Y': [4, 4, 5, 5, 8, np.nan]})
So, I want to replace nan's in Y column that correspond to observations in X with "*NY" part, to numbers in Y that correspond to observations in X that have the same numeric part but without "*NY"
This was a bit more annoying to code, basically we can apply a custom function that performs the lookup for you:
In [106]:
# define our function
def func(x):
# test to see if the asterisk is present
if x.find('*') > 0:
# perform a lookup on a slice of the passed in string
return(current_data.loc[current_data.X==x[0:x.find('*')],'Y'].values.max())
# using loc assign to column 'Y' where it is null the returned calculation of the apply
current_data.loc[current_data.Y.isnull(),'Y'] = current_data[current_data.Y.isnull()]['X'].apply(func)
current_data
Out[106]:
X Y
0 3*NY 4
1 3 4
2 2 5
3 2*NY 5
4 1 8
5 7 NaN