pandas read_html: how to read columns that contain ? - html

I am trying to read a html-table with python that looks like this:
+------------+---------+
| ID | Value |
+------------+---------+
| 1 | 12 098 |
| 2 | 20 |
| 3 | 123 456 |
+------------+---------+
In html-code the elements look like this:
<span> 123 456</span>
Pandas reads this as object but I need it to be numeric. I tried:
df_tables=pd.read_html(table_html,header=0,thousands=' ')
and
df_tables=pd.read_html(table_html,header=0,thousands=' ')
But the column is always 'object'.
I tried casting to float:
df_table['Value']=df_table['Value'].apply(pd.to_numeric,errors='coerce')
But that just deleted the values in the columns where there was a blank space.
Subsequently I tried to strip the space from the column before applying to numeric:
df_table=df_table['Value'].map(lambda x: x.strip(' '))
But that doesn't seem to have any effect. I'd prefer to fix this while reading the html but I am happy to accept any solution that gives me a numeric column at this point.
Update:
I can not remove from the source html because there are other columns that contain text.

Try using:
df_table['Value'] = df_table['Value'].str.replace('\D', '').astype(int)

Another way to approach this
import pandas as pd
html_string = """
<table>
<thead>
<tr>
<th>ID</th>
<th>value</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>1 230</td>
</tr>
<tr>
<td>2</td>
<td>100</td>
</tr>
<tr>
<td>3</td>
<td>220</td>
</tr>
</tbody>
</table>
"""
html_string = html_string.replace(" ","")
df_table = pd.read_html(html_string)
dfs = df_table[0]
for (index, row) in dfs.iterrows():
print(float(row[1]))

Related

Create table columns by *ngFor

I try to make table in Angular. How can I create table columns by e.g *ngFor?
I have lists
Data [
​0:
data: [
0: 0
1: 4
2: 4
3: 3
4: 5
5: 1
​​​]
id: 49
label: "Label_1"
​​
1:
data:[
0: 5
1: 0
2: 1
3: 5
4: 0
5: 0
​​​]
id: 50
label: "label_2"
]
---- SECOND ARRAY-----
Array [
0: "value_"
1: "value_"
2: "value_"
3: "value_"
4: "value_"
5: "value_"
]
and I'd like to recieve this:
| # | label_1 | label_2 | label_3 |
--------------------------------------------------
|Value1 | 1 | 4 | 7 |
|Value2 | 2 | 5 | 8 |
|Value3 | 3 | 6 | 9 |
--------------------------------------------------
Data will be appended to the "array", and I wish these columns were created automatically. I click button 'add data to array' and a new column is created. It does not necessarily have to be ngFor. Could someone help me do something like this?
One possible way to do it is to have a table like this in HTML:
<table border="1">
<thead>
<th>#</th>
<th *ngFor="let column of array">
{{column}}
</th>
</thead>
<tbody>
<tr *ngFor="let row of values; index as i">
<td>{{row}}</td>
<td *ngFor="let column of array; index as j">
{{numbers[j][i]}}
</td>
</tr>
</tbody>
</table>
First ngFor is for columns, 2nd is for rows and the third is for values
Working Stackblitz
Update
With new data format:
<table border="1">
<thead>
<th>#</th>
<th *ngFor="let column of array">
{{column.name}}
</th>
</thead>
<tbody>
<tr *ngFor="let row of values; index as i">
<td>{{row}}</td>
<td *ngFor="let column of array; index as j">
{{array[j].numbers[i]}}
</td>
</tr>
</tbody>
</table>
Working Stackblitz
Update 2nd
To make fields editable use ngModel like this:
<input type="number" class="form-control" [(ngModel)]="array[j].numbers[i]">
Stackblitz

get all records of same string under one title in laravel

I am currently getting records from multiple table by using join in laravel. But my issue is that the under the teacher name all records will show those have same teacher name others should be in next table like that
e.g
Teacher1 name
id name class subject
1 student1 8 chem
2 student2 9 phy
teacher2 name
3 student3 9 chem
4 student4 11 chem
teacher3 name
......
here is my laravel view
<table class="table">
<thead>
#foreach($students as $student)
<tr style="background-color: #e9e5e4;">
<td colspan="4">{{$student->teacher_name}}</td>
</tr>
<tr>
<th>Name</th>
<th>Class</th>
<th>Subject</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{$student->name }}</td>
<td>{{$student->class}} </td>
<td>{{$student->subject }} </td>
</tr>
#endforeach
</tbody>
</table>
but according to above code I have multiple issues like teacher name is repeating if duplicate entry found in database and I can't make teacher name unique because I need multiple entry of same name , secondly all records are showing under every teacher. my current output is like that
Teacher1 name
id name class subject
1 student1 8 chem
2 student2 9 phy
3 student3 9 chem
4 student4 11 chem
Teacher2 name
id name class subject
1 student1 8 chem
2 student2 9 phy
3 student3 9 chem
4 student4 11 chem
I assume that $students is collection. Then you can use the groupBy
method. You can rewrite your code like this:
#php
$index = 1;
#endphp
#foreach($students->groupBy('teacher_name') as $teacherName => $subStudents)
<h2>{{$teacherName}}</h2>
<table class="table">
<thead>
<tr>
<th>No.</th>
<th>Name</th>
<th>Class</th>
<th>Subject</th>
</tr>
</thead>
<tbody>
#foreach($subStudents as $student)
<tr>
<td>{{$index }}</td>
<td>{{$student->name }}</td>
<td>{{$student->class}} </td>
<td>{{$student->subject }} </td>
</tr>
#php
$index++;
#endphp
#endforeach
</tbody>
</table>
#endforeach
Let me know if that answer your question.

Place TD elements next to each other

I have this small (maybe simple) question. I have a table right now which is displayed as a normal table.
-------------------
| item 1 | item 4 |
-------------------
| item 2 | item 5 |
-------------------
| item 3 | item 6 |
-------------------
This works fine for most pages (layout wise) but I've got this same table on an other page where the layout of this table doesnt fit the div it's in. So I was thinking can I align the table data next to each other, using CSS:
-------------------------------------------------------
| item 1 | item 2 | item 3 | item 4 | item 5 | item 6 |
-------------------------------------------------------
I've tried a couple of things I found using google.
display:inline-block;,display:inline-table;,float:left. Now IS this at all possible? I know you can do it the other way round, using display:block.
Here is my HTML:
<table>
<tr>
<td><i class='fa fa-users' aria-hidden='true'></i></td>
<td><p>". chop($str,"-999") . "</p></td>
</tr>
<tr>
<td><i class='fa fa-clock-o' aria-hidden='true'></i></td>
<td><p>" . $row["Tijdsduur"] . "</p></td>
</tr>
<tr>
<td><i class='fa fa-euro' aria-hidden='true'></i></td>
<td><p><small>" . $var . "</small></p></td>
</tr>
</table>
I've tried a couple of things I found using google. display:inline-block;
And that will do it.
td { border: solid black 1px; }
tr, td { display: inline-block; }
<table>
<tr>
<td><i class='fa fa-users' aria-hidden='true'></i></td>
<td>
<p>". chop($str,"-999") . "</p>
</td>
</tr>
<tr>
<td><i class='fa fa-clock-o' aria-hidden='true'></i></td>
<td>
<p>" . $row["Tijdsduur"] . "</p>
</td>
</tr>
<tr>
<td><i class='fa fa-euro' aria-hidden='true'></i></td>
<td>
<p><small>" . $var . "</small></p>
</td>
</tr>
</table>

Style certain rows from database table in html table

I have a html table received from this query:
SELECT proj_title, CONCAT(projectNo, " ", proj_title) AS title
FROM (
SELECT projectNo, CONCAT("Project ", title) AS proj_title, 0 AS a FROM project p1
UNION ALL
SELECT DISTINCT projectNo, process, 1 AS a FROM process p2
) t
ORDER BY projectNo, a, title
And table:
<table class="paginated" style=" margin-right:10%;">
<?php
$header ='<th>Title</th>';
echo "<thead>$header</thead>";
while ($data = mysqli_fetch_assoc($query))
{
$projectNo = $data['proj_title'];
$body = '<td>'.$projectNo.'</td>';
echo "<tbody>$body</tbody>";
}
?>
</table>
The table looks like this:
| title |
+-----------------+
| Project test |
| ANM |
| BLD |
| Project test2 |
| ANM KEY |
| BLD |
Is there any way to style only certain rows like: | Project test || Project test2 |
How it can be done?
Yes, you certainly can style individual rows in a table with CSS. Your provided structure doesn't actually include any table rows (<tr> elements), so you might want to fix that up first. <tbody> is not a valid child of <td>, and <td> must be contained inside a <tr>.
Once you fix up your table structure, you can target every nth row with the pseudo-selector :nth-of-type:
tr:nth-of-type(3n) {
color: #f00;
}
<table>
<tr>
<td>One</td>
</tr>
<tr>
<td>Two</td>
</tr>
<tr>
<td>Three</td>
</tr>
<tr>
<td>Four</td>
</tr>
<tr>
<td>Five</td>
</tr>
<tr>
<td>Six</td>
</tr>
</table>
In the above sample, 3n represents that it should target every third row, and change the colour.
You could also alternatively add a class to the specific rows that you wish to target through PHP itself, and then simply target that class directly with CSS:
echo "<tr class='red'><td>$data</td></tr>";
.red {
color: #ff0;
}
Hope this helps! :)

How to create nested cells inside the same table TD

I have the following table:-
<table class="table table-striped">
<thead>
<tr>
<th></th>
</tr>
</thead>
<tbody>
#foreach(var permisionMag in Model.PermisionManagement)
{
<tr>
<td>#permisionMag.Name</td>
#{
int i = 0;
<td class="f">
#foreach(var item in permisionMag.TechnologyTypes.OrderBy(a => a.Name)) {
#(i+1) #item.Name
i = i + 1;
}
<br />
</td>
}
</tr>
}
</tbody>
</table>
But currently i need the second column to have nested rows instead of showing the rows inside the same TD? any advice on this?
You can not generate directly table cells, you have to generate a new table inside the second table cell.
You could also render #item.Name as a span/div and style that to create the illusion of a nested table(jsFiddle example).
You can use rowspan on the first column :
<table class="table table-striped">
<thead>
<tr>
<th></th>
</tr>
</thead>
<tbody>#foreach(var permisionMag in Model.PermisionManagement) {
<tr>
<td rowspan="#permisionMag.TechnologyTypes.Count()">#permisionMag.Name</td>
#{
int i = 0;
foreach (var item in permisionMag.TechnologyTypes.OrderBy(a => a.Name))
{
i = i + 1;
if( i > 1) {
</tr><tr>
}
<td class="f">
#(i+1) #item.Name
</td>
}
}
</tr>
}
</tbody>
</table>
See expecting result
I hope it helps.
If I understand your question, then you probably want to do this:
#foreach(var permisionMag in Model.PermisionManagement) {
<tr>
<td rowspan="#permisionMag.TechnologyTypes.Count()">#permisionMag.Name</td>
#{int i = 0;
#foreach (var item in permisionMag.TechnologyTypes.OrderBy(a => a.Name)) {
<td class="f">
#(i+1) #item.Name
i = i + 1;
</td>
</tr>
<tr>
}
</tr>
}
}
But it should essentially build you something like this:
----------------
| Name | Item1 |
| | ----- |
| | Item2 |
| | ----- |
| | Item3 |
| | ----- |
| | Item4 |
----------------