How to count specific column data in CSV file using PHP [duplicate] - php

This question already has answers here:
How to count non-empty entries in a PHP array?
(5 answers)
Closed last year.
I have one CSV file. It contains 3 columns I want to count only the 3rd column total rows. I tried with one code but It showed the whole CSV file rows counts.
$record = file('filename.csv', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$total_record = count($record);
echo $total_record; // output 6
As per the below image, I want to count only the Ph_no column. Please help me out

You could use array_map() to run callback str_getcsv() on each element (row) in the array that is returned by file().
$arr = array_map('str_getcsv', file('./filename.csv'));
The result ($arr) would look something like this:
Array
(
[0] => Array
(
[0] => First_Name
[1] => Last_name
[2] => Ph_no
)
[1] => Array
(
[0] => ABC
[1] => AB
[2] => 1234567890
)
... etc.
You can then count the number of phone numbers:
$phNo = array_column($arr, 2);
$phNoCount = count($phNo) -1 ; // subtract the header
echo 'Ph_no count: ' . $phNoCount;

$file = fopen('myCSVFile.csv', 'r');
$count = 0;
while (($line = fgetcsv($file)) !== FALSE) {
$num = count($line);
for ($i=0; $i < $num; $i++) {
if(!empty($line[2]) {
$count++;
}
}
}
fclose($file);
echo $count;

Using the fgetcsv() function it is quite simple
$tot = 0;
if (($f = fopen("filename.csv", "r")) !== FALSE) {
// read and ignore first line, titles
fgetcsv($f, 1000, ",");
while (($line = fgetcsv($f, 1000, ",")) !== FALSE) {
if ( $line[2] !== '' ) {
$tot += $line[2]; // accumulate column 3
}
}
}
fclose($f);
echo $tot;

Related

PHP convert CSV to serialized array

I have a CSV file with 2 columns, id and key. An extract is...
26,"test1
test2
test3
"
54,"test34
test52
test673
"
67,"test1
test2a
test333
"
I am trying to load this file into PHP and convert the second field (key) into a serialized array, I have this so far...
$filename = 'myfile.csv';
if (($h = fopen("{$filename}", "r")) !== FALSE) {
while (($data = fgetcsv($h, 1000, ",")) !== FALSE) {
var_dump($data[1]);
}
fclose($h);
}
I am now trying to loop through the lines in $data[1] to convert them into an array, but when I do a var_dump the new lines seems to have disapeard. Am i approaching this the correct way?
Not sure what you meant by a serialized array here but I assume you want to make your key to be in a single line like below. LET ME KNOW IF I AM WRONG. So lets try like this way-
<?php
$fp = fopen('file.csv', 'r');
$csvArray = array();
while ($row = fgetcsv($fp)) {
$csvArray[$row[0]] = preg_replace("/[\r\n]/"," ",$row[1]);
}
fclose($fp);
print_r($csvArray);
?>
Output:
Array
(
[26] => test1 test2 test3
[54] => test34 test52 test673
[67] => test1 test2a test333
)

Reading data from a text file using Strpos & Substr to remove commas between and a while loop to repeat for each row

I'll try and be as clear as I can with what my problem is here, I've been working on this one for a while now and can't seem to get my head around it. Basically, I'm trying to:
Read numbers from a text file & store them in a 2D array
Remove any commas in the text file and store the remaining data in a table format
Using strpos & substr to extract the data, leaving behind unwanted commas
Then using a while loop to repeat this process so every line in the text file is read one at a time until all the lines are read.
At first my code was stating what lines I had errors in and I have since amended but now the php page doesnt seem to load at all. Is there some sort of error within my while loop statement?
Here is the php code I'm currently working with that doesnt seem to be loading:
$fileopen = fopen($file,'r') or die("Sorry, cannot find the file $file");
if($fileopen){
while (($buffer=fgets($fileopen,4096))!==false){
}
if(!feof($fileopen)){
echo "Error:unexpected fgets() fail\n";
}
fclose($fileopen);
}
$filearray = array();
$rows = 0;
$columns = 0;
$fileopen = fopen($file,'r') or die("Sorry, cannot open $file");
while(!feof($fileopen))
{
$line = fgets($fileopen);
$length = strlen($line);
$pos = 0;
$comma = 0;
while($pos < length) {
$comma = strpos($line,",",$comma);
$filearray[$rows][$columns] = substr($line,$pos,$comma);
$pos = $comma +1;
$columns++;
}
$columns = 0;
$rows++;
}
This section is essentially displaying the extracted data from the text file in a table format:
function array_transpose($filearray)
{
array_unshift($filearray, NULL);
return call_user_func_array('array_map', $filearray);
}
echo"<h1></h1>";
echo "<table border = 0 >";
for($row=0; $row<$count; $row++){
print "<tr>";
for($col=0; $col<$count; $col++){
echo "<td>".$array[$row][$col]."</td>";
}
}
echo "</table>";
It was quite the challenge for me to get this one to work, but I managed to do it. I've put comments inside the code to explain what's happening. The reasons it didn't work for you (as I said in the comments) was because you were creating an infinite loop. The $pos integer was always smaller than your $length integer. So the while() loop would never break.
Another issue that you didn't encounter yet was the use of $comma as the length for substr(). Because strpos() returns you the actual position and not the position relative to the offset, this would cause problems. That's why you needed to save the previous position of the delimiter (comma) and substract that from the current position of the delimiter.
Anyway, here is my example code. It's giving you the result that you need. It's up to you to incorporate it into your own code.
<?php
// Initial variables
$result = array();
$key = 0;
// Open the file
$handle = fopen("numbers.txt", "r");
if ($handle) {
while (($line = fgets($handle)) !== false) {
// First we set the delimiter into a variable
$delimiter = ',';
// Some integers we're going to use for our loop
$pos = 0; // The current position
$comma = 0; // Position of the next comma
$innerkey = 0; // Key used for the 2D result array
$previous = 0; // Previous comma position
$loops = 0; // Number of loops
$nr_commas = substr_count($line, $delimiter); // Number of commas in a single line
while($loops <= $nr_commas) {
// Get the position of the next comma
$comma = strpos($line,$delimiter,$comma);
// Make sure a comma is found
if($comma !== false){
// Put the substring into the result array using $pos as the offset
// and calculating the length by substracting the position of the previous
// comma from the current comma.
$result[$key][$innerkey] = substr($line,$pos,$comma - $previous);
// Add 1 to the previous comma or it will include the current comma in the result
$previous = $comma + 1;
$pos = $comma + 1;
$innerkey++;
$loops++;
$comma++;
} else {
// In case no more commas are found, we still need to add the last integer
$loops++;
$result[$key][$innerkey] = substr($line,strrpos($line,$delimiter)+1);
}
}
$key++;
}
fclose($handle);
} else {
echo "Unable to open the file";
}
echo "<pre>";
print_r($result);
echo "</pre>";
?>
TXT File used:
3,34,2,35,4,234,34,2,53,4
5,4,23,6,67,324,5,34,5
345,67,3,45,6,7
Result:
Array
(
[0] => Array
(
[0] => 3
[1] => 34
[2] => 2
[3] => 35
[4] => 4
[5] => 234
[6] => 34
[7] => 2
[8] => 53
[9] => 4
)
[1] => Array
(
[0] => 5
[1] => 4
[2] => 23
[3] => 6
[4] => 67
[5] => 324
[6] => 5
[7] => 34
[8] => 5
)
[2] => Array
(
[0] => 345
[1] => 67
[2] => 3
[3] => 45
[4] => 6
[5] => 7
)
)

import csv in array's, explode text file by datevalue given or by numrows possible?

I have a csv file which Contains Trace Signals of Vibration Data.
Its Starts with an ISO 8601 Date 2017-01-31T16:16:21.000+01:00
then it have 1024 rows of data(512Hz 2Sec Signal). And then the next Trace signal which starts with the new Date but in the same file -.-.
2017-01-31T16:16:21.000+01:00
0,06;0,03;0,01
0,07;0,03;0,01
0,07;0,03;0,02
.... up to line 1025
2017-01-31T16:24:37.000+01:00
1,72;0,2;-0,9
1,48;0,39;-1,46
1,23;0,58;-1,67
0,99;0,76;-1,81
... up to line 2050
This file can contain much more than 2 traces, how can i pass this in seperated arrays ? i would prefer arrays like :
Array
(
[0] => Array
(
[Time] => 2017-01-31T16:16:21.000
[Data] => array ( [0] => 0,06;0,03;0,01
[1] => 0,07;0,03;0,01 etc..)
)
But I don't know how to loop through the file and explode by the datetime value and also use it. Other way was To read Firstline as Time and next 1024 rows by line and push it but how ?
You may run into problems as your array gets larger, but this is the approach:
$i = $j = 0;
if($handle = fopen('/path/to/file.csv', 'r')) {
while(($line = fgets($handle)) !== false) {
if($i % 1025 === 0) {
$j++;
$result[$j]['Time'] = $line;
} else {
$result[$j]['Data'][] = $line;
}
$i++;
}
}
Just loop through the file and test if it is the first line or one that is a multiple of 1026. If it is, then you are on a line with the time, if not it is the data.

Split a Comma Separated Value of a Field

I am trying to import a CSV for a shop, with a subset of data from an existing CSV file. I need to split one item from a column (column 3, category_id) that contains multiple comma-separated values, then combine it with one other column (Product_id) to produce multiple rows in the import CSV. See the following examples.
Original CSV
Product_id;article_id;category_id;
"1";"0001";"2,4,6"
Need it into a new CSV file
Product_id;category_id
"1";"2"
"1","4"
"1","6"
I tried just the fegetcsv function to read in the CSV and to printout the whole into an array but I have no idea what to do next.
<?php
$handle = fopen ("articles.csv","r");
while ( ($data = fgetcsv ($handle, 1000, ";")) !== FALSE ) {
$column3[] = $data[3];
}
fclose ($handle);
//edit:
print_r($column3);
?>
I get:
Array ([0] => category_id [1] => 1 [2] => 0001 [3] => 2,4,6
Quick and dirty:
$csvData = file('articles.csv');
$matches = array();
$output = "";
foreach($csvData as $csvLine) {
if(preg_match('/"(.+)";".+";"(.+)"/', $csvLine, $matches))
{
$numbers = explode(',', $matches[2]);
foreach($numbers as $number) {
$output .= "\"{$matches[1]}\";\"{$number}\"" . PHP_EOL;
}
}
}

How can I pull 2 paired elements from a csv file and add them to an array using PHP?

I have several csv files that contain order information for products. My csv files look something like below:
order_number,sku,qty,price_per,total_price
12345,55555,25,4,100
12346,33333,10,5,50
12347,55555,20,4,80
I'm not having any trouble finding out the total_price for all transactions, but how can I find the totals on each product? I tried creating an array for each, but I can't figure out how to keep the sku and total_price elements bound together.
Update #2
Since I can't have an array with matching keys, and since I want to end up here anyway, how can I get an array like this:
Array(
[55555] => 180
[33333] => 50
)
If anyone has any ideas on how I can make this array that would be great. Thanks!
Update #1
Sorry, I spaced adding my code, here it is:
foreach($files as $file){
$fh = fopen($file, 'rb');
while($col = fgetcsv($fh)) {
$csv[] = $col;
$total = array($col[27])
}}
This will do what you want, i.e. create an array $totals which sums the totals over skus:
$totals = array();
foreach($files as $file) {
$fh = fopen($file, 'rb');
while($col = fgetcsv($fh)) {
$csv[] = $col;
$total = array($col[27])
$totals[$col[1]] += $col[27];
}
}
Current answers don't produce the array you're after:
Array(
[55555] => 100
[33333] => 50
[55555] => 80
)
Because this can't be done - 55555 can't be used as a key twice. An alternative would be to have an array of the form:
Array(
[12345] => array("sku"=>55555,"total_price"=>100),
[12346] => array("sku"=>33333,"total_price"=>50),
[12347] => array("sku"=>55555,"total_price"=>80),
)
This code produces the second array:
$trans = array();
foreach($files as $file){
$fh = fopen($file, 'rb');
while($col = fgetcsv($fh)) {
$trans[$col[0]] = array("sku"=>$col[0],"total_price"=>$col[27]);
}
}
Assuming $col[0] is order and $col[1] is sku.

Categories