I am trying to write the output into xslx file, but able to only write the headers not able to write the data below headers.
import xlsxwriter
csv_columns = (
'id', 'name', 'place', 'salary', 'email',
)
details = [{'id':1, 'name': 'A', 'place':'B', 'salary': 2, 'email': 'c#d.com'},
{'id':3, 'name':'C', 'place':'D', 'salary': 4, 'email':'e#f.com'}]
workbook = xlsxwriter.Workbook(path)
worksheet = workbook.add_worksheet()
for col, name in enumerate(csv_columns):
worksheet.write(0, col, name)
for row, det in enumerate(details, 1):
for col, value in enumerate(det):
worksheet.write(row, col, value)
workbook.close()
This code is only writing the csv_columns in xslx file and repeating same in all rows as below
id name place salary email
id name place salary email
id name place salary email
How to solve this issue of repeating columns in xslx? any help ?
I expected like below:
id name place salary email
1 A B 2 c#d.com
3 C D 4 e#f.com
from openpyxl import Workbook
wb = Workbook()
ws = wb.active
csv_columns = (
'id', 'name', 'place', 'salary', 'email',
)
details = [{'id':1, 'name': 'A', 'place':'B', 'salary': 2, 'email': 'c#d.com'},
{'id':3, 'name':'C', 'place':'D', 'salary': 4, 'email':'e#f.com'}]
details_values = [tuple(d.values()) for d in details]
details_values.insert(0, csv_columns)
for row in details_values:
print(row)
ws.append(row)
wb.save(output_file_path)
I corrected your code. Now it works as you would expect:
import xlsxwriter
csv_columns = (
'id', 'name', 'place', 'salary', 'email',
)
values = [(1, 'A', 'B', 2, 'c#d.com'),
(3, 'C', 'D', 4, 'e#f.com')]
workbook = xlsxwriter.Workbook(path)
worksheet = workbook.add_worksheet()
row, col = 0, 0
worksheet.write_row(row, col, csv_columns)
row += 1
for value in values:
worksheet.write_row(row, col, value)
row += 1
workbook.close()
It would probably be best to map your dictionaries into a list of lists and then process it that way, but here is one way of doing it based on your sample code:
import xlsxwriter
csv_columns = ('id', 'name', 'place', 'salary', 'email')
details = [{'id': 1, 'name': 'A', 'place': 'B', 'salary': 2, 'email': 'c#d.com'},
{'id': 3, 'name': 'C', 'place': 'D', 'salary': 4, 'email': 'e#f.com'}]
workbook = xlsxwriter.Workbook("test.xlsx")
worksheet = workbook.add_worksheet()
worksheet.write_row(0, 0, csv_columns)
for row, det in enumerate(details, 1):
for col, key in enumerate(csv_columns):
worksheet.write(row, col, det.get(key, ''))
workbook.close()
Output:
Related
i have the below dataframe i want to filter the dataframe and return result based on the user selection from a multiselectbox , and grouped by name
the selectbox is the unique value of name field
import streamlit as st
import pandas as pd
data = {
'ID': [1, 2, 3, 4],
'name': ['peter', 'john', 'james', 'james'],
'nickname': ['pet', 'jon','james', 'jem'],
'mother_name': ['maria', 'linda', 'ana', 'beth'],
'bd': ['2000-05-15', '2006-09-12', '2004-10-25',]
}
with st.sidebar.form(key='search_form',clear_on_submit= False):
choices =df["name"].unique().tolist()
regular_search_term = st.multiselect(" ",choices)
if st.form_submit_button("search"):
df_result_search=df[df["name"].isin(regular_search_term)]
df_group = df_result_search.groupby('name')
st.write(df_group)
if i select james it return the 2 records while i need to return
1 record that includes the 2 data related to james
how can i return this result.
There is a missing value for the key bd in your data dictionnary.
You can use this :
import streamlit as st
import pandas as pd
data = {
'ID': [1, 2, 3, 4],
'name': ['peter', 'john', 'james', 'james'],
'nickname': ['pet', 'jon', 'james', 'jem'],
'mother_name': ['maria', 'linda', 'ana', 'beth'],
'bd': ['2000-05-15', '2006-09-12', '2004-10-25', '2004-10-26']
}
df = pd.DataFrame(data)
with st.sidebar.form(key='search_form', clear_on_submit=False):
choices = df["name"].unique().tolist()
regular_search_term = st.multiselect(" ", choices)
if st.form_submit_button("search"):
st.text('Filter on name')
st.write(df[df["name"].isin(regular_search_term)])
st.text('Filter on nickname')
st.write(df[df["nickname"].isin(regular_search_term)])
df_gr = df[['ID', 'nickname', 'mother_name', 'bd']
].astype(str).groupby(df['name']).agg('|'.join).reset_index()
st.text('Filter on name with grouped columns')
st.write(df_gr[df_gr["name"].isin(regular_search_term)])
>>> Output (in browser):
I let you choose whatever type of filter/display you want between the three.
My default dict has an address key and has a list of dictionaries that match that key. I'd like to export this defaultdict to a csv file.
See below:
Right now my structure looks like this defaultdict(list)
#As you can see 1 key with multiple matching dictionaries.
#And im just copying 1 address but I have ~10 w/ varying matches
defaultdic1 =
defaultdict(list,
{'Address_1': [{'Name': 'name',
'Address_match': 'address_match_1',
'ID': 'id',
'Type': 'abc'},
{'Name': 'name',
'Address_match': 'address_match_2',
'ID': 'id',
'Type': 'abc'},
{'Name': 'name',
'Address_match': 'address_match_3',
'ID': 'id',
'Type': 'abc'}]})
I tried doing this:
json_data = json.dumps(data_json, indent=2)
jsondf = pd.read_json(json_data, typ = 'series')
and my result was this:
Address 1 [{'Name':'name', 'Address_match':'address_match_1' 'ID' : 'id', 'Type':'abc'} {'Name':'name', 'Address_match':'address_match_2' 'ID' : 'id', 'Type':'abc'}, {'Name':'name', 'Address_match':'address_match_3' 'ID' : 'id', 'Type':'abc'}]
Result/output:
Id like to export this to an excel file
Update I tried this. The first row is printing the key but 2nd row is still in a {}, it would be great to get them out of the brackets and shifted into columns. Any tips there?
for k, v in defaultdict.items():
f.writerow([k])
for values in v:
f.writerow([values])
results in CSV are:
Address 1
{'Name':'name', 'Address_match':'address_match_1' 'ID' : 'id', 'Type':'abc'}
{'Name':'name', 'Address_match':'address_match_1' 'ID' : 'id', 'Type':'abc'}
{'Name':'name', 'Address_match':'address_match_2' 'ID' : 'id', 'Type':'abc'}
I'd like my results to be:
Address 1 Name, Address_match1, ID, Type
Name, Address_match2, ID, Type
Name, Address_match3, ID, Type
Address 2 Name1, Address_match1, ID, Type
Name1, Address_match1, ID, Type
Address 3 Name1, Address_match1, ID, Type
Name1, Address_match1, ID, Type
Your input data and output data do not match, so it's awfully difficult to tell how to transform things, but here is something that takes your defaultdict and converts it to a CSV file:
import csv
dic1 = {'Address_2':
[
{'Address 1':
[
{'Name':'name', 'Address_match':'address_match_1', 'ID':'id', 'Type':'abc'}
]
},
{'Address 2':
[
{'Name':'name', 'Address_match':'address_match_2', 'ID':'id', 'Type':'abc'}
]
},
{'Address 3':
[
{'Name':'name', 'Address_match':'address_match_3', 'ID':'id', 'Type':'abc'}
]
}
]
}
names = list(dic1['Address_2'][0]['Address 1'][0].keys())
myfile = csv.DictWriter( open('xxx.csv','w'), fieldnames = names )
for row in dic1['Address_2']:
myfile.writerow({'Name':list(row.keys())[0]})
myfile.writerow(list(row.values())[0][0])
This is what ended up solving it!
names = list(dic1['Address_1'][0].keys())
f.close()
with open ("file.csv", "w", newline="") as f:
writer = csv.writer(f)
keys = names
writer.writerow(["Address"] +(keys))
for k, vl in defaultdict.items():
for v in vl:
writer.writerow([k] + [v[key] for key in keys])
f.close()
For this same Stack Overflow question How do I output a list of dictionaries to an Excel sheet?.
For xlsx code by jossef-harush we can use this:
import xlsxwriter
# ...
def create_xlsx_file(file_path: str, headers: dict, items: list):
with xlsxwriter.Workbook(file_path) as workbook:
worksheet = workbook.add_worksheet()
worksheet.write_row(row=0, col=0, data=headers.values())
header_keys = list(headers.keys())
for index, item in enumerate(items):
row = map(lambda field_id: item.get(field_id, ''), header_keys)
worksheet.write_row(row=index + 1, col=0, data=row)
headers = {
'bank': 'Money in Bank',
'dailyWinners': 'Daily Winners',
'dailyFree': 'Daily Free',
'user': 'User',
}
players = [
{'dailyWinners': 3, 'dailyFreePlayed': 2, 'user': 'Player1', 'bank': 0.06},
{'dailyWinners': 3, 'dailyFreePlayed': 2, 'user': 'Player2', 'bank': 4.0},
{'dailyWinners': 1, 'dailyFree': 2, 'user': 'Player3', 'bank': 3.1},
{'dailyWinners': 3, 'dailyFree': 2, 'user': 'Player4', 'bank': 0.32}
]
create_xlsx_file("my xslx file.xlsx", headers, players)
For creating a CSV file, what are the changes I need to do in the above code?
Like create_csv_file("my csv file.csv", headers, players).
import csv
def create_csv_file(file_path, headers, items):
with open(file_path, "wt") as f:
dw = csv.DictWriter(f, headers.values(), extrasaction='ignore')
dw.writeheader()
for row in items:
dw.writerow({headers.get(k): v for (k, v) in row.items()})
writes
Money in Bank,Daily Winners,Daily Free,User
0.06,3,,Player1
4.0,3,,Player2
3.1,1,2,Player3
0.32,3,2,Player4
Note that this will ignore any dict keys not in headers; in your case, the dailyFreePlayeds.
I am making a program that reads data from a form, stores it into a dictionary, and then uses csv.DictWrite to make append the data to a csv file. I run the program but nothing happens to my data.csv file. The main program and the data file are in the same working directory, and csvmodule is installed as well.
Here's the code,
def response_to_csv(data):
#append w/ dictionary -> more efficiewn
with open('data.csv', 'a', newline = '') as csvfile:
fieldnames = ['date', 'first', 'last', 'age', 'email', 'country',
'city/town', 'Uni Student', 'Instagram','Followers','Affiliate'
]
writer = csv.DictWriter(csvfile, fieldnames = fieldnames)
writer.writeheader()
writer.writerow({
'date' : data['date'],
'first': data['first'],
'last' : data['last'],
'age' : data['age'],
'email': data['email'],
'country': data['country'],
'city/town': data['city/town'],
'Uni Student': data['Uni Student'],
'Instagram': data['Instagram'],
'Followers': data['Followers'],
'Affiliate': data['Affiliate']
})
Here's the data dictionary
data = {
'date' : date,
'first': fname,
'last' : lname,
'age' : age,
'email': email,
'country': country,
'city/town': city_town,
'Uni Student': is_Uni_Student,
'Instagram': insta,
'Followers': ig_followers,
'Affiliate': affiliation
}
response_to_csv(data)
import csv
data = {
'date' : '202001',
'first': 'Bob',
'last' : 'Smith',
'age' : 45,
'email': 'bsmith#gmail.com',
'country': 'USA',
'city/town': 'New York',
'Uni Student': 1,
'Instagram': '#bsmith',
'Followers': 45678,
'Affiliate': 'Red Bull'
}
def response_to_csv(data):
fieldnames = ['date', 'first', 'last', 'age', 'email', 'country',
'city/town', 'Uni Student', 'Instagram','Followers','Affiliate'
]
with open('data.csv', 'a', newline = '') as csvfile:
writer = csv.DictWriter(csvfile, fieldnames = fieldnames)
writer.writeheader()
writer.writerow(data)
response_to_csv(data)
Your code worked for me, although I had to fix the indentation of the body of your function, with open(...) should not be at the same indent as def response_to_csv(data):
import csv
def response_to_csv(data):
#append w/ dictionary -> more efficiewn
with open('data.csv', 'a', newline = '') as csvfile:
fieldnames = ['date', 'first', 'last', 'age', 'email', 'country',
'city/town', 'Uni Student', 'Instagram','Followers','Affiliate'
]
writer = csv.DictWriter(csvfile, fieldnames = fieldnames)
writer.writeheader()
writer.writerow({
'date' : data['date'],
'first': data['first'],
'last' : data['last'],
'age' : data['age'],
'email': data['email'],
'country': data['country'],
'city/town': data['city/town'],
'Uni Student': data['Uni Student'],
'Instagram': data['Instagram'],
'Followers': data['Followers'],
'Affiliate': data['Affiliate']
})
data = {
'date' : '2019_01_01',
'first': 'firstname',
'last' : 'lname',
'age' : '99',
'email': 'email#address.com',
'country': 'USA',
'city/town': 'MyTown',
'Uni Student': True,
'Instagram': 'MyInsta',
'Followers': 24,
'Affiliate': 'affiliation'
}
response_to_csv(data)
$ cat data.csv
date,first,last,age,email,country,city/town,Uni Student,Instagram,Followers,Affiliate
2019_01_01,firstname,lname,99,email#address.com,USA,MyTown,True,MyInsta,24,affiliation
This is my file: test.txt
Amy|Female|Desc1|12
John|Male|Desc2|10
Mike|Male|Desc3|18
I tried to create nested dictionary and it's not sucessful.
This is the output:
{'Amy': '12', 'John': '10', 'Mike': '18'}
This is my code:
import csv
with open('test.txt') as file:
tsvfile = csv.reader(file, delimiter='|')
d = {}
for row in tsvfile:
d[row[0]] = row[0] #this should be name
d[row[0]] = row[1] #this should be gender
d[row[0]] = row[3] #this should be desc
d[row[0]] = row[3] #this should be age
print(d)
My desired output as below but was not successful.
d={1{'Name':'Amy', 'Gender':'Female', 'Desc': 'Desc1', 'Age': '12'}
2{'Name':'John', 'Gender':'Male', 'Desc': 'Desc2', 'Age': '10'}
3{'Name':'Mike', 'Gender':'Male', 'Desc': 'Desc3', 'Age': '18'}}
and below (with name and age only
d1={1{'Name':'Amy','Age': '12'}
2{'Name':'John', 'Age': '10'}
3{'Name':'Mike', 'Age': '18'}}
Here's how to do it without csv import, given the data format is constant:
fixed = {}
i = 1
with open("test.txt", 'r') as f:
for line in f:
listDetails = line.strip().split('|')
fixed[i] = {"Name": listDetails[0]}
fixed[i].update({"Sex": listDetails[1]})
fixed[i].update({"Description": listDetails[2]})
fixed[i].update({"Age": listDetails[3]})
i+=1
print(fixed)
This should turn
Amy|Female|Desc1|12
John|Male|Desc2|10
Mike|Male|Desc3|18
To
{1: {'Name': 'Amy', 'Sex': 'Female', 'Description': 'Desc1', 'Age': '12'}, 2: {'Name': 'John', 'Sex': 'Male', 'Description': 'Desc2', 'Age': '10'}, 3: {'Name': 'Mike', 'Sex': 'Male', 'Description': 'Desc3', 'Age': '18'}}
Edit: Just as Nakor said though, it doesn't really make sense to make a dict of dicts here, just posted this if you really need to make it a dict.
1) Nested Dictionary, I have made some changes in the same code, it may help you.
import csv
with open('hello.txt') as file:
tsvfile = csv.reader(file, delimiter='|')
final_dict = {}
counter = 1
for row in tsvfile:
d = {}
d['Name'] = row[0] #this should be name
d['Gender'] = row[1] #this should be gender
d['Desc'] = row[2] #this should be desc
d['Age'] = row[3] #this should be age
final_dict[counter] = d
counter+=1
print(final_dict)
Your desired output looks more like a list of dictionaries.
In this case, I would just modify your code like this:
import csv
with open('test.txt') as file:
tsvfile = csv.reader(file, delimiter='|')
d = []
for row in tsvfile:
entry = {
'Name': row[0],
'Gender': row[1],
'Desc': row[2],
}
d.append(entry)
print(d)
Output:
[{'Name': 'Amy', 'Gender': 'Female', 'Desc': 'Desc1'},
{'Name': 'John', 'Gender': 'Male', 'Desc': 'Desc2'},
{'Name': 'Mike', 'Gender': 'Male', 'Desc': 'Desc3'}]
You can even write the loop in a more compact way like this:
keys = ["Name","Gender","Desc"]
for row in tsvfile:
entry = { key: value for (key,value) in zip(keys,row) }
d.append(entry)
EDIT: If you want a dictionary with the line number as keys, you can do:
import csv
with open('test.txt') as file:
tsvfile = csv.reader(file, delimiter='|')
d = {}
keys = ["Name","Gender","Desc"]
for i,row in enumerate(tsvfile):
entry = {
'Name': row[0],
'Gender': row[1],
'Desc': row[2],
}
d[i+1] = entry
print(d)