Import csv file with sep=';' to python by columns - Pandas Dataset - python-3.x

I have a csv file like this:
ATTRIBUTE_1;.....;ATTRIBUTE_N
null;01;M;N;;N;1108;1;F205;;N;F;13;;N;S;2;N;6000000;;A010;40;B;2;10;42;N;;61;MI;01;N;N;S;;-1;N;N;01;;;;;;;;;;;;;;;;;;;;;;;;;;778,69
null;01;M;N;;N;1108;1;F205;;N;F;13;;N;S;2;N;6000000;;A010;40;B;2;10;42;N;;61;MI;01;N;N;S;;-1;N;N;01;;;;;;;;;;;;;;;;;;;;;;;;;;778,71
null;01;M;N;;N;1108;1;F205;;N;F;13;;N;S;2;N;6000000;;A010;40;B;2;10;42;N;;61;MI;01;N;N;S;;-1;N;N;01;;;;;;;;;;;;;;;;;;;;;;;;;;778,72
When i try to import in python with this comand:
data = pd.read_csv(r"C:\...\file.csv")
My output is this:
0 null;01;M;N;;N;1108;1;F205;;N;F;13;;N;S;2;N;60...
How can a import a csv by columns? Like this:
ATTRIBUTE_1 ATTRIBUTE_2 .... ATTRIBUTE_N
NULL 01 778,69
NULL 01 778,71
...
NULL 03 775,33

There is problem your each row start and end with ", so is necessary parameter quoting=3, it means set QUOTE_NONE:
df = pd.read_csv('file.csv', sep=';', quoting=3)
#strip " from first and last column
df.iloc[:,0] = df.iloc[:,0].str.strip('"')
df.iloc[:,-1] = df.iloc[:,-1].str.strip('"')
#strip " from columns names
df.columns = df.columns.str.strip('"')
print (df.head())
SIGLA TARGA CATEGORIA TARIFFARIA - LIVELLO 3 SESSO \
0 null 1 M
1 null 1 M
2 null 1 M
3 null 1 M
4 null 1 M
RCA - PATTO PER I GIOVANI VALORE FRANCHIGIA TIPO TARGA CILINDRATA \
0 N NaN N 1108
1 N NaN N 1108
2 N NaN N 1108
3 N NaN N 1108
4 N NaN N 1108
CODICE FORMA CONTRATTUALE RCA - RECUPERO COMUNE PRA \
0 1 F205
1 1 F205
2 1 F205
3 1 F205
4 1 F205
CODICE WORKSITE MARKETING ... Unnamed: 55 Unnamed: 56 \
0 NaN ... NaN NaN
1 NaN ... NaN NaN
2 NaN ... NaN NaN
3 NaN ... NaN NaN
4 NaN ... NaN NaN
Unnamed: 57 Unnamed: 58 Unnamed: 59 Unnamed: 60 Unnamed: 61 Unnamed: 62 \
0 NaN NaN NaN NaN NaN NaN
1 NaN NaN NaN NaN NaN NaN
2 NaN NaN NaN NaN NaN NaN
3 NaN NaN NaN NaN NaN NaN
4 NaN NaN NaN NaN NaN NaN
Unnamed: 63 PREMIO FINALE
0 NaN 778,69
1 NaN 778,70
2 NaN 778,71
3 NaN 778,72
4 NaN 778,73
[5 rows x 65 columns]

Related

pandas.errors.ParserError: Expected 5 fields in line 3, saw 6

I am trying to read a data file using pandas,
import pandas as pd
file_path = "/home/gopakumar/Downloads/test.DAT"
df = pd.read_csv(file_path, header=None, sep=';', engine='python',encoding="windows-1252")
and getting the following error:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python3.8/dist-packages/pandas/io/parsers.py", line 610, in read_csv
return _read(filepath_or_buffer, kwds)
File "/usr/local/lib/python3.8/dist-packages/pandas/io/parsers.py", line 468, in _read
return parser.read(nrows)
File "/usr/local/lib/python3.8/dist-packages/pandas/io/parsers.py", line 1057, in read
index, columns, col_dict = self._engine.read(nrows)
File "/usr/local/lib/python3.8/dist-packages/pandas/io/parsers.py", line 2496, in read
alldata = self._rows_to_cols(content)
File "/usr/local/lib/python3.8/dist-packages/pandas/io/parsers.py", line 3189, in _rows_to_cols
self._alert_malformed(msg, row_num + 1)
File "/usr/local/lib/python3.8/dist-packages/pandas/io/parsers.py", line 2948, in _alert_malformed
raise ParserError(msg)
pandas.errors.ParserError: Expected 5 fields in line 3, saw 6
From the error description, I understand that the file has a different number of columns in each row, but this is how the file is, and is there any way to read such a file with a different number of columns in each row.
Following is a sample file:
0050;V2019.8.0.0;V2019.8.0.0;20200407;184821
0070;;7;0;7
0080;11;50;Abcd.pdf;Abcd;C:\Daten\Ablage\
0090;1;H;Holz;0;0;0;Holz;;;Holz
0090;1;Z;Abcdör;0;0;0;Abcd;;;Abcd
0090;1;N;Abcd;0;0;0;Abcd;;;Abcd
If you use header = None all rows must have same no of cols like below:
data = """
0050;V2019.8.0.0;V2019.8.0.0;20200407;184821;;;;;;;;;;;
0070;;7;0;7
0080;11;50;Abcd.pdf;Abcd;C:\Daten\Ablage\
0090;1;H;Holz;0;0;0;Holz;;;Holz
0090;1;Z;Abcdör;0;0;0;Abcd;;;Abcd
0090;1;N;Abcd;0;0;0;Abcd;;;Abcd
"""
df = pd.read_csv(StringIO(data), header=None, sep=';')
Output:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0 50 V2019.8.0.0 V2019.8.0.0 20200407 184821 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
1 70 NaN 7 0 7 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2 80 11 50 Abcd.pdf Abcd C:\Daten\Ablage0090 1.0 H Holz 0.0 0 0.0 Holz NaN NaN Holz
3 90 1 Z Abcdör 0 0 0.0 Abcd NaN NaN Abcd NaN NaN NaN NaN NaN
4 90 1 N Abcd 0 0 0.0 Abcd NaN NaN Abcd NaN NaN NaN NaN NaN
Or if you know how many columns are there in the data you can also use:
cols = [f'col_{i}' for i in range(0,16)]
df = pd.read_csv(StringIO(data), names=cols, sep=';')
Output:
col_0 col_1 col_2 col_3 col_4 col_5 col_6 col_7 col_8 col_9 col_10 col_11 col_12 col_13 col_14 col_15
0 50 V2019.8.0.0 V2019.8.0.0 20200407 184821 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
1 70 NaN 7 0 7 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2 80 11 50 Abcd.pdf Abcd C:\Daten\Ablage0090 1.0 H Holz 0.0 0 0.0 Holz NaN NaN Holz
3 90 1 Z Abcdör 0 0 0.0 Abcd NaN NaN Abcd NaN NaN NaN NaN NaN
4 90 1 N Abcd 0 0 0.0 Abcd NaN NaN Abcd NaN NaN NaN NaN NaN

Trying to add content to an existing dataFrame

I've been trying for days to find a solution to my problem. I am trying to add content to a pre-existing column in a data frame, however when I print the screen my program shows me that only the first 100 lines are being modified, it is never shown beyond line 100 and the items are not added but overwritten. I've tried several ways and it always gives an error, the closest way to what I want is this print that I put in the post. Could someone help me, I would be very grateful.
import functions
import pandas as pd
from time import sleep
from selenium import webdriver
from selenium.webdriver.firefox.options import Options
pd.set_option('max_rows', 10)
# Module of which the page link returns
site = functions.pagina()
#Browser Options
options = Options()
options.headless = True # Prevent browser from opening
driver = webdriver.Firefox(options=options) #Include options in browser
#Run browser with URL
driver.get(site)
# Wait in seconds for the page to load
print('Esperando 5s')
sleep(5)
#Create Data Frame
df = pd.DataFrame(columns = ['rank','nome','classe','item_lvl','servidor','mortes_temporada'], index=None)
while True:
#Get the 'next page' variable
next_page = driver.find_element_by_css_selector('#pagination-hook > nav > ul > li:nth-child(2) > a')
#As long as the Next variable is empty
if next_page is not None:
#Url of current page
driver.get(driver.current_url)
print(driver.current_url[-6:].upper())
#Attempting to insert data into existing rank column
ranks = pd.Series([rank_page.text for rank_page in driver.find_elements_by_xpath('//div[4]//div[1]/table/tbody/tr/td[1]')])
#MY PROBLEM ADDING CONTENT TO A COLUMN
df['rank'] =+ ranks
#Click on Next
driver.execute_script("arguments[0].click();", next_page)
sleep(4)
else:
break
print('*' * 80)
print(df)
print('*' * 80)
RETURN PRINT - IMAGE
Esperando 5s
PAGE=1
********************************************************************************
rank nome classe item_lvl servidor mortes_temporada
0 1 NaN NaN NaN NaN NaN
1 2 NaN NaN NaN NaN NaN
2 3 NaN NaN NaN NaN NaN
3 4 NaN NaN NaN NaN NaN
4 5 NaN NaN NaN NaN NaN
.. ... ... ... ... ... ...
95 96 NaN NaN NaN NaN NaN
96 97 NaN NaN NaN NaN NaN
97 98 NaN NaN NaN NaN NaN
98 99 NaN NaN NaN NaN NaN
99 100 NaN NaN NaN NaN NaN
[100 rows x 6 columns]
********************************************************************************
PAGE=2
********************************************************************************
rank nome classe item_lvl servidor mortes_temporada
0 101 NaN NaN NaN NaN NaN
1 102 NaN NaN NaN NaN NaN
2 103 NaN NaN NaN NaN NaN
3 104 NaN NaN NaN NaN NaN
4 105 NaN NaN NaN NaN NaN
.. ... ... ... ... ... ...
95 196 NaN NaN NaN NaN NaN
96 197 NaN NaN NaN NaN NaN
97 198 NaN NaN NaN NaN NaN
98 199 NaN NaN NaN NaN NaN
99 200 NaN NaN NaN NaN NaN
[100 rows x 6 columns]
********************************************************************************
When you add data to a column in Pandas, and df is a DataFrame, you have to include data for the rest of the columns for every row.
In your case, the fix is:
df2 = pd.DataFrame({
"rank": [rank_page.text for rank_page in driver.find_elements_by_xpath('//div[4]//div[1]/table/tbody/tr/td[1]')],
"nome": np.nan,
"classe": np.nan,
"item_lvl": np.nan,
"servidor": np.nan,
"mortes_temporada": np.nan
})
df = df.append(df2)

Merging rows in pandas DataFrame

I am writing a script to scrape a series of tables in a pdf into python using tabula-py.
This is fine. I do get the data. But the data is multi-line, and useless in reality.
I would like to merge the rows where the first column (Tag is not NaN).
I was about to put the whole thing in an iterator, and do it manually, but I realize that pandas is a powerful tool, but I don't have the pandas vocabulary to search for the right tool. Any help is much appreciated.
My Code
filename='tags.pdf'
tagTableStart=2 #784
tagTableEnd=39 #822
tableHeadings = ['Tag','Item','Length','Description','Value']
pageRange = "%d-%d" % (tagTableStart, tagTableEnd)
print ("Scanning pages %s" % pageRange)
# extract all the tables in that page range
tables = tabula.read_pdf(filename, pages=pageRange)
How The data is stored in the DataFrame:
(Empty fields are NaN)
Tag
Item
Length
Description
Value
AA
Some
2
Very Very
Text
Very long
Value
AB
More
4
Other Very
aaaa
Text
Very long
bbbb
Value
cccc
How I want the data:
This is almost as it is displayed in the pdf (I couldn't figure out how to make text multi line in SO editor)
Tag
Item
Length
Description
Value
AA
Some\nText
2
Very Very\nVery long\nValue
AB
More\nText
4
Other Very\nVery long\n Value
aaaa\nbbbb\ncccc
Actual sample output (obfuscated)
Tag Item Length Description Value
0 AA PYTHROM-PARTY-I 20 Some Current defined values are :
1 NaN NaN NaN texst Byte1:
2 NaN NaN NaN NaN C
3 NaN NaN NaN NaN DD
4 NaN NaN NaN NaN NaN
5 NaN NaN NaN NaN DD
6 NaN NaN NaN NaN DD
7 NaN NaN NaN NaN DD
8 NaN NaN NaN NaN NaN
9 NaN NaN NaN NaN B :
10 NaN NaN NaN NaN JLSAFISFLIHAJSLIhdsflhdliugdyg89o7fgyfd
11 NaN NaN NaN NaN ISFLIHAJSLIhdsflhdliugdyg89o7fgyfd
12 NaN NaN NaN NaN upon ISFLIHAJSLIhdsflhdliugdyg89o7fgy
13 NaN NaN NaN NaN asdsadct on the dasdsaf the
14 NaN NaN NaN NaN actsdfion.
15 NaN NaN NaN NaN NaN
16 NaN NaN NaN NaN SLKJDBFDLFKJBDSFLIUFy7dfsdfiuojewv
17 NaN NaN NaN NaN csdfgfdgfd.
18 NaN NaN NaN NaN NaN
19 NaN NaN NaN NaN fgfdgdfgsdfgfdsgdfsgfdgfdsgsdfgfdg
20 BB PRESENT-AMOUNT-BOX 11 Lorem Ipsum NaN
21 CC SOME-OTHER-VALUE 1 sdlkfgsdsfsdf 1
22 NaN NaN NaN device NaN
23 NaN NaN NaN ueghkjfgdsfdskjfhgsdfsdfkjdshfgsfliuaew8979vfhsdf NaN
24 NaN NaN NaN dshf87hsdfe4ir8hod9 NaN
Create groups from ID columns then join each rows:
agg_func = dict(zip(df.columns, [lambda s: '\n'.join(s).strip()] * len(df.columns)))
out = df.fillna('').groupby(df['Tag'].ffill(), as_index=False).agg(agg_func)
Output:
>>> out
Tag Item Length Description Value
0 AA Some\nText 2 Very Very\nVery long\nValue
1 AB More\nText 4 Other Very\nVery long\nValue aaaa\nbbbb\ncccc
agg_func is equivalent to write:
{'Tag': lambda s: '\n'.join(s).strip(),
'Item': lambda s: '\n'.join(s).strip(),
'Length': lambda s: '\n'.join(s).strip(),
'Description': lambda s: '\n'.join(s).strip(),
'Value': lambda s: '\n'.join(s).strip()}

Concatenating Pandas dataframes, getting Nan values for first dataframe

I'm trying to join two dataframes. 'df' is my initial dataframe containing all the header information I require. 'row' is my first row of data that I want to append to 'df'.
df =
FName E1 E2 E3 E4 E5 E6
0 Nan 2 2 2 2 2 2
1 Nan 1 1 1 1 1 1
2 Nan 3 4 5 6 7 8
3 Nan 4 5 6 7 8 10
4 Nan 1002003004 1002004005 1002005006 1002006007 1002007008 1002008010
row =
0 1 2 3 4 5 6
0 501#_ZMB_2019-04-03_070528_reciprocals 30.0193 30.0193 30.0193 34.8858 34.8858 34.8858
I'm trying to create this:
FName E1 E2 E3 E4 E5 E6
0 Nan 2 2 2 2 2 2
1 Nan 1 1 1 1 1 1
2 Nan 3 4 5 6 7 8
3 Nan 4 5 6 7 8 10
4 Nan 1002003004 1002004005 1002005006 1002006007 1002007008 1002008010
5 501#_ZMB_2019-04-03_070528_reciprocals 30.0193 30.0193 30.0193 34.8858 34.8858 34.8858
I have tried the following:
df = df.append(row, ignore_index=True)
and
df = pd.concat([df, row], ignore_index=True)
Both of these result in the loss of all the data in the first df, which should contain all the header information.
0 1 2 3 4 5 6
0 Nan Nan Nan Nan Nan Nan Nan
1 Nan Nan Nan Nan Nan Nan Nan
2 Nan Nan Nan Nan Nan Nan Nan
3 Nan Nan Nan Nan Nan Nan Nan
4 Nan Nan Nan Nan Nan Nan Nan
5 501#_ZMB_2019-04-03_070528_reciprocals 30.0193 30.0193 30.0193 34.8858 34.8858 34.8858
I've also tried
df = pd.concat([df.reset_index(drop=True, inplace=True), row.reset_index(drop=True, inplace=True)])
Which produced the following Traceback
Traceback (most recent call last):
File "<ipython-input-146-3c1ecbd1987c>", line 1, in <module>
df = pd.concat([df.reset_index(drop=True, inplace=True), row.reset_index(drop=True, inplace=True)])
File "C:\Users\russells\AppData\Local\Continuum\anaconda3\lib\site-packages\pandas\core\reshape\concat.py", line 228, in concat
copy=copy, sort=sort)
File "C:\Users\russells\AppData\Local\Continuum\anaconda3\lib\site-packages\pandas\core\reshape\concat.py", line 280, in __init__
raise ValueError('All objects passed were None')
ValueError: All objects passed were None
Does anyone know what I'm doing wrong?
When you concatenate extra rows, pandas aligns the columns, which currently do not overlap. rename will get the job done:
pd.concat([df, row.rename(columns=dict(zip(row.columns, df.columns)))],
ignore_index=True)
FName E1 E2 E3 E4 E5 E6
0 Nan 2 2 2 2 2 2
1 Nan 1 1 1 1 1 1
2 Nan 3 4 5 6 7 8
3 Nan 4 5 6 7 8 10
4 Nan 1002003004 1002004005 1002005006 1002006007 1002007008 1002008010
5 501#_ZMB_2019-04-03_070528_reciprocals 30.0193 30.0193 30.0193 34.8858 34.8858 34.8858
Or if you just need to assign one row at the end and you have a RangeIndex on df:
df.loc[df.shape[0], :] = row.to_numpy()

Replace column values according to corresponding values of other column in Pandas

I am trying to replace value of columns on basis of column. for example col1 has values in first 5 rows and col2 has values so update col1 values according to col2.
For next five rows there are no value in col1 but col2 have value just skip these rows dont need to update col1, and so on.
df9["col1"].replace(["s1"], "data_value", inplace=True)
i used this code line from Replacing few values in a pandas dataframe column with another value. It gives me output just replace value with data value , not replace with values inside data value column.
Dataframe
col1 col2 col3 col4
0 s1 NaN NaN NaN
1 s1 NaN NaN NaN
2 s1 NaN NaN NaN
3 s1 NaN NaN NaN
4 s1 NaN NaN NaN
5 NaN s2 NaN NaN
6 NaN s2 NaN NaN
7 NaN s2 NaN NaN
8 NaN s2 NaN NaN
9 NaN s2 NaN NaN
10 NaN NaN ss1 NaN
11 NaN NaN ss1 NaN
12 NaN NaN ss1 NaN
13 NaN NaN ss1 NaN
14 NaN NaN ss1 NaN
15 NaN NaN NaN ss333
16 NaN NaN NaN ss333
17 NaN NaN NaN ss333
18 NaN NaN NaN ss333
19 NaN NaN NaN ss333
Desired output:
col1 col2 col3 col4
0 0 NaN NaN NaN
1 0 NaN NaN NaN
2 0 NaN NaN NaN
3 0 NaN NaN NaN
4 0 NaN NaN NaN
5 NaN 0 NaN NaN
6 NaN 0 NaN NaN
7 NaN 0 NaN NaN
8 NaN 0 NaN NaN
9 NaN 0 NaN NaN
10 NaN NaN 500 NaN
11 NaN NaN 500 NaN
12 NaN NaN 500 NaN
13 NaN NaN 500 NaN
14 NaN NaN 500 NaN
15 NaN NaN NaN 500
16 NaN NaN NaN 500
17 NaN NaN NaN 500
18 NaN NaN NaN 500
19 NaN NaN NaN 500
Use mask for replace all not missing values with pop for extract column Data:
df = pd.DataFrame({
'A':[4,5] + [np.nan] * 4,
'B':[np.nan,np.nan,9,4,np.nan,np.nan],
'C':[np.nan] * 4 + [7,0],
'Data':list('aaabbb')
})
print (df)
A B C Data
0 4.0 NaN NaN a
1 5.0 NaN NaN a
2 NaN 9.0 NaN a
3 NaN 4.0 NaN b
4 NaN NaN 7.0 b
5 NaN NaN 0.0 b
df = df.mask(df.notnull(), df.pop('Data'), axis=0)
print (df)
A B C
0 a NaN NaN
1 a NaN NaN
2 NaN a NaN
3 NaN b NaN
4 NaN NaN b
5 NaN NaN b
Alternatively you can also use where
df = pd.DataFrame({'col1': ['s1']*5+[np.nan]*15,
'col2':[np.nan]*5+['s2']*5+[np.nan]*10,
'col3':[np.nan]*10+['ss1']*5+[np.nan]*5,
'col4':[np.nan]*15+['ss333']*5,
'data_value':[0]*10+[500]*10 })
df = df.where(df.isnull(), df.pop('data_value'), axis = 0)
col1 col2 col3 col4
0 0 NaN NaN NaN
1 0 NaN NaN NaN
2 0 NaN NaN NaN
3 0 NaN NaN NaN
4 0 NaN NaN NaN
5 NaN 0 NaN NaN
6 NaN 0 NaN NaN
7 NaN 0 NaN NaN
8 NaN 0 NaN NaN
9 NaN 0 NaN NaN
10 NaN NaN 500 NaN
11 NaN NaN 500 NaN
12 NaN NaN 500 NaN
13 NaN NaN 500 NaN
14 NaN NaN 500 NaN
15 NaN NaN NaN 500
16 NaN NaN NaN 500
17 NaN NaN NaN 500
18 NaN NaN NaN 500
19 NaN NaN NaN 500

Resources