Writing to one column using openpyxl - python

I want to write the values of the list values only on column A of the new workbook, for example:
a1 = 1
a2 = 2
a3 = 3
etc. etc. but right now I get this:
a1 = 1 b1 = 2 c1= 3 d1= 4
a1 = 1 b1 = 2 c1= 3 d1= 4
a1 = 1 b1 = 2 c1= 3 d1= 4
My code:
# create new workbook and worksheet
values = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
wb = Workbook(write_only = True)
ws = wb.create_sheet()
for row in range(0, len(values)):
ws.append([i for i in values])
wb.save('newfile.xlsx')
this code above fills all the cells in range A1:A15 to O1:O15
I only want to fill the values in column A1:A15

Not yet tested, but I would think
Tested-- you have a syntax error also; substitute 'row' for 'i'. But the following works.
for row in range(0, len(values)):
ws.append([row])

You need to create nested list to append the values in column, refer below code.
from openpyxl import Workbook
values = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
wb = Workbook()
ws = wb.create_sheet()
newlist = [[i] for i in values]
print(newlist)
for x in newlist:
ws.append(x)
wb.save('newfile.xlsx')

Related

Openpyxl: Concatenation of several columns into one cell per row (Multi-row)

This question is a follow up to: Openpyxl: TypeError - Concatenation of several columns into one cell per row
What I want to do:
I want to concatenate the cells from columns F to M per row and put the concatenated value into column E like below. This needs to be done for all rows at the same time.
Input:
A B C D E F G H .. M
....... E1 90 2A .. 26
....... 0 80 F8 ..
Output:
A B C D E F G H .. M
....... E1902A..26
....... 080F8..
Code:
def concat_f_to_m():
for row_value in range(1, sheet.max_row+1):
values=[]
del values[:]
for row in sheet.iter_rows(min_col=6, max_col=14, min_row=row_value, max_row=row_value):
for cell in row:
if cell.value != None:
values.append(str(cell.value))
else:
del values[:]
pass
sheet[f'E{row_value}'].value= ''.join(values)
concat_f_to_m()
Also I have set the max column to column N (14) as the longest code goes until column M and I want to stop the loop once there is no entry found in order to go out and join the list's items. I cannot overcome the issue that despite a print of the values list shows only the row's items, it does not write it down into the cell.
Could you give me a hint how to concatenate through all rows by joining the values list at the certain row? Thank you!
Correct implementation:
def concat_f_to_m():
for row_value in range(1, sheet.max_row+1):
values=[]
del values[:]
for row in sheet.iter_rows(min_col=6, max_col=14, min_row=row_value, max_row=row_value):
for cell in row:
if cell.value != None:
values.append(str(cell.value))
sheet[f'E{row_value}'].value= ''.join(values)
else:
del values[:]
break
concat_f_to_m()

using previous row value by looping through index conditioning

If i have dataframe with column x.
I want to make a new column x_new but I want the first row of this new column to be set to a specific number (let say -2).
Then from 2nd row, use the previous row to iterate through the cx function
data = {'x':[1,2,3,4,5]}
df=pd.DataFrame(data)
def cx(x):
if df.loc[1,'x_new']==0:
df.loc[1,'x_new']= -2
else:
x_new = -10*x + 2
return x_new
df['x_new']=(cx(df['x']))
The final dataframe
I am not sure on how to do this.
Thank you for your help
This is what i have so far:
data = {'depth':[1,2,3,4,5]}
df=pd.DataFrame(data)
df
# calculate equation
def depth_cal(d):
z = -3*d+1 #d must be previous row
return z
depth_cal=(depth_cal(df['depth'])) # how to set d as previous row
print (depth_cal)
depth_new =[]
for row in df['depth']:
if row == 1:
depth_new.append('-5.63')
else:
depth_new.append(depth_cal) #Does not put list in a column
df['Depth_correct']= depth_new
correct output:
There is still two problem with this:
1. it does not put the depth_cal list properly in column
2. in the depth_cal function, i want d to be the previous row
Thank you
I would do this by just using a loop to generate your new data - might not be ideal if particularly huge but it's a quick operation. Let me know how you get on with this:
data = {'depth':[1,2,3,4,5]}
df=pd.DataFrame(data)
res = data['depth']
res[0] = -5.63
for i in range(1, len(res)):
res[i] = -3 * res[i-1] + 1
df['new_depth'] = res
print(df)
To get
depth new_depth
0 1 -5.63
1 2 17.89
2 3 -52.67
3 4 159.01
4 5 -476.03

openpyxl: Fetch value from excel and store in key value pair

Have written a python script that fetches the cell values and displays in a list row by row.
Here is my script:
book = openpyxl.load_workbook(excel_file_name)
active = book.get_sheet_by_name(excel_file_name)
def iter_rows(active):
for row in active.iter_rows():
yield [cell.value for cell in row]
res = list(iter_rows(active))
for new in res:
print new
Output for the above script:
[state, country, code]
[abc, xyz, 0][def, lmn, 0]
I want output in below format:
[state:abc, country:xyz, code:0][state:def, country:lmn, code:0]
Please note: I want to do this from openpyxl
I think this should do exactly what you want.
import openpyxl
book = openpyxl.load_workbook("Book1.xlsx")
active = book.get_sheet_by_name("Sheet1")
res = list(active)
final = []
for x in range(1, len(res)):
partFinal = {}
partFinal[res[0][0].value] = res[x][0].value
partFinal[res[0][1].value] = res[x][1].value
partFinal[res[0][2].value] = res[x][2].value
final.append(partFinal)
for x in final:
print x

Writing a list to excel

I am trying to do the following:
For each entry in Col A, if that entry recurs in the same Col A, then add together all of its values in Col E.
Then, write only that (added) values from Col E into another excel sheet. Each Col A entry should have all the Col E values corresponding to it.
However, I can create that output sheet for the last row only.
Here is the code that I've written,
#! /usr/bin/env python
from xlrd import open_workbook
from tempfile import TemporaryFile
from xlwt import Workbook
wb = open_workbook('/Users/dem/Documents/test.xlsx')
wk = wb.sheet_by_index(0)
for i in range(wk.nrows):
a = str(wk.cell(i,0).value)
b = []
e = []
for j in range(wk.nrows):
c = str(wk.cell(j,0).value)
d = str(wk.cell(j,4).value)
if a == c:
b.append(d)
print b
e.append(b)
book = Workbook()
sheet1 = book.add_sheet('sheet1')
n = 0
for n, item in enumerate(e):
sheet1.write(n,0,item)
n +=1
book.save('/Users/dem/Documents/res.xls')
book.save(TemporaryFile())
Erred resulting sheet(mine):
Comments in the code.
#! /usr/bin/env python
from xlrd import open_workbook
from tempfile import TemporaryFile
from xlwt import Workbook
import copy
wb = open_workbook('C:\\Temp\\test.xls')
wk = wb.sheet_by_index(0)
# you need to put e=[] outside the loop in case they are reset to empty list every loop
# e is used to store final result
e = []
# f is used to store value in Col A which means we only record value once
f = []
for i in range(wk.nrows):
b = []
temp = None
a = str(wk.cell(i,0).value)
#here we only record value once
if a in f:
continue
#here you should start from i+1 to avoid double counting
for j in range(i+1, wk.nrows):
c = str(wk.cell(j,0).value)
if a == c:
# you can put operations here in order to make sure they are executed only when needed
d = str(wk.cell(j,4).value)
k = str(wk.cell(i,4).value)
f.append(a)
# record all the value in Col E
b.append(k)
b.append(d)
# you need to use deepcopy here in order to get accurate value
temp = copy.deepcopy(b)
# in your case, row 5 has no duplication, temp for row 5 will be none, we need to avoid adding none to final result
if temp:
e.append(temp)
book = Workbook()
sheet1 = book.add_sheet('sheet1')
n = 0
for n, item in enumerate(e):
sheet1.write(n,0,item)
# you don't need n+=1 here, since n will increase itself
book.save('C:\\Temp\\res.xls')
book.save(TemporaryFile())
I think you should look forward to use csv.writer with dialect='excel' There is an example in this documentation on usage. I think this is just the simplest way to work with excel if you don't need huge functionality like in your case.

to add column values in a specific manner in a csv file using python

i have a csv file similar to the following :
title title2 h1 h2 h3 ...
l1.1 l1 1 1 0
l1.2 l1 0 1 0
l1.3 l1 1 0 1
l2.1 l2 0 0 1
l2.2 l2 1 0 1
l3.1 l3 0 1 1
l3.2 l3 1 1 0
l3.3 l3 1 1 0
l3.4 l3 1 1 0
i want to be able to add the columns in the following manner:
h1 ( l1.1 + l1.2+ l1.3 ) = 2
h1 ( l2.1 + l2.2 ) = 1
h1 ( l3.1 + l3.2 + l3.3 +l3.4) = 3 and so on for every column
And i want the final count for every such value as a summarised table :
title2 h1 h2 h3...
l1 2 2 1
l2 1 0 2
l3 3 4 1
how do i implement this?
Something like this should work. It takes an input in the form
title,title2,h1,h2,h3
l1.1,l1,1,1,0
l1.2,l1,0,1,0
l1.3,l1,1,0,1
l2.1,l2,0,0,1
l2.2,l2,1,0,1
l3.1,l3,0,1,1
l3.2,l3,1,1,0
l3.3,l3,1,1,0
l3.4,l3,1,1,0
and outputs
title2,h1,h2,h3
l1,2,2,1
l2,1,0,2
l3,3,4,1
Tested with Python 3.1.2. In Python 2.x you'll need to change the open() calls to use binary mode, and drop the newline="" bit). You can also drop the call to list() since in Python 2.x, map() already returns a list.
import csv
import operator
reader = csv.reader(open("test.csv", newline=""), dialect="excel")
result = {}
for pos, entry in enumerate(reader):
if pos == 0:
headers = entry
else:
if entry[1] in result:
result[entry[1]] = list(map(operator.add, result[entry[1]], [int(i) for i in entry[2:]]))
else:
result[entry[1]] = [int(i) for i in entry[2:]]
writer = csv.writer(open("output.txt", "w", newline=""), dialect="excel")
writer.writerow(headers[1:])
keys = sorted(result.keys())
for key in keys:
output = [key]
output.extend(result[key])
writer.writerow(output)
Have a look at the csv module. What you want to do is open the file with a csv.reader. Then you iterate over the file, one row at the time. You accumulate the results of the additions into a temporary list. When you are done, you write this list to a new csv.writer.
You might need to define a dialect as you are not really using CSV but some tab-delimited format.

Categories

Resources