fputcsv - Как генерировать CSV без вложений в PHP [duplicate]

Это было давно, но я столкнулся с такой же проблемой. И нашел здесь много интересных ответов. Поэтому я смутил, какой метод использовать.

В случае добавления большого количества строк в dataframe мне интересна скорость. Итак, я пробовал 3 самых популярных метода и проверял их скорость.

СКОРОСТЬ ПРОИЗВОДИТЕЛЬНОСТИ

  1. Использование .append ( Ответ NPE )
  2. Использование ответа .loc ( fred и FooBar )
  3. Использование dict и создание DataFrame в конце ( Ответ ShikharDua ])

Результаты (в секундах):

Adding    1000 rows  5000 rows   10000 rows
.append   1.04       4.84        9.56
.loc      1.16       5.59        11.50
dict      0.23       0.26        0.34

Поэтому я использую дополнение через словарь для себя.


Код :

import pandas
import numpy
import time

numOfRows = 10000
startTime = time.perf_counter()
df1 = pandas.DataFrame(numpy.random.randint(100, size=(5,5)), columns=['A', 'B', 'C', 'D', 'E'])
for i in range( 1,numOfRows):
    df1 = df1.append( dict( (a,numpy.random.randint(100)) for a in ['A','B','C','D','E']), ignore_index=True)
print('Elapsed time: {:6.3f} seconds for {:d} rows'.format(time.perf_counter() - startTime, numOfRows))

startTime = time.perf_counter()
df2 = pandas.DataFrame(numpy.random.randint(100, size=(5,5)), columns=['A', 'B', 'C', 'D', 'E'])
for i in range( 1,numOfRows):
    df2.loc[df2.index.max()+1]  = numpy.random.randint(100, size=(1,5))[0]
print('Elapsed time: {:6.3f} seconds for {:d} rows'.format(time.perf_counter() - startTime, numOfRows))

startTime = time.perf_counter()
row_list = []
for i in range (0,5):
    row_list.append(dict( (a,numpy.random.randint(100)) for a in ['A','B','C','D','E']))
for i in range( 1,numOfRows):
    dict1 = dict( (a,numpy.random.randint(100)) for a in ['A','B','C','D','E'])
    row_list.append(dict1)

df3 = pandas.DataFrame(row_list, columns=['A','B','C','D','E'])
print('Elapsed time: {:6.3f} seconds for {:d} rows'.format(time.perf_counter() - startTime, numOfRows))

PS Я считаю, что моя реализация не идеальна, и, возможно, есть какая-то оптимизация.

40
задан Derek Reynolds 26 November 2009 в 00:31
поделиться

10 ответов

Предупреждения о вышесказанном корпусе действительны, но вы сказали, что они не применяются к вашему прецеденту.

Мне интересно, почему вы не можете просто использовать что-то вроде этого?

<?php
$fields = array(
    "field 1","field 2","field3hasNoSpaces"
);
fputs(STDOUT, implode($fields, ',')."\n");
53
ответ дан oops 27 August 2018 в 01:20
поделиться
  • 1
    Не знаю, почему я не пошел первым. Благодаря! – Derek Reynolds 15 December 2009 в 23:23
  • 2
    Поскольку библиотеки CSV обрабатывают случаи, которые нет в вашем простом решении implode, например, экранирование символа разделителя (, в вашем случае). – jgomo3 8 February 2016 в 23:43
  • 3
    Это лучший способ заменить fputcsv без корпусов. Я бы сделал небольшое предложение улучшить этот ответ: используйте документированный порядок аргументов для implode : implode(string $glue, array $pieces), чтобы избежать путаницы с людьми, которые являются новыми для PHP и не знают эту функцию PHP & quot; обратных аргументов. – hrvoj3e 16 December 2016 в 12:25

Я использую сложный способ удалить двойную кавычку, но только в Linux

....
fputcsv($fp, $product_data,"\t");
....
shell_exec('sed -i \'s/"//g\' /path/to/your-file.txt ');
0
ответ дан Ansyori 27 August 2018 в 01:20
поделиться

Не работает ли это?

fputcsv($fp, split(',', $line),',',' ');
2
ответ дан Arthur Frankel 27 August 2018 в 01:20
поделиться
  • 1
    Split будет устаревшей функцией, и это не обязательно решает мою проблему с приложениями. К сожалению, пробелы не считаются законным персонажем, по крайней мере, насколько эта функция. Спасибо хоть! – Derek Reynolds 26 November 2009 в 00:47
  • 2
    Если предположить, что дополнительное пространство не является проблемой, похоже, он ищет no корпус; однако использование пространства кажется логичным, чтобы попробовать. – Tim Lytle 26 November 2009 в 00:48

Выяснил это. Передавая в ascii-код для Null функции car(), он работает нормально.

fputcsv($f, $array, $delimiter, car(0))

Спасибо за ответы всем !!!

1
ответ дан Derek Reynolds 27 August 2018 в 01:20
поделиться
  • 1
    Хм ... ты уверен, что он не собирается вставлять кучу стелс-нулей в файл csv? : s Также, я думаю, что это «chr (0)» -! – user 26 June 2012 в 19:35
  • 2
    Накладывает NULL для меня. Не идеальное решение. – Shadowbob 22 July 2013 в 14:56

Это то, что я использую для добавления стандартного CSV в массив ...

function csv_explode($delim=',', $str, $enclose='"', $preserve=false){
        $resArr = array();
        $n = 0;
        $expEncArr = explode($enclose, $str);
        foreach($expEncArr as $EncItem){
                if($n++%2){
                        array_push($resArr, array_pop($resArr) . ($preserve?$enclose:'') . $EncItem.($preserve?$enclose:''));
                }else{
                        $expDelArr = explode($delim, $EncItem);
                        array_push($resArr, array_pop($resArr) . array_shift($expDelArr));
                        $resArr = array_merge($resArr, $expDelArr);
                }
        }
        return $resArr;
} 

Затем вы можете выводить все, что хотите, в цикле foreach.

0
ответ дан jjclarkson 27 August 2018 в 01:20
поделиться

Недостаток файла CSV без вложений означает, что ошибочная запятая в пользовательском вводе будет забивать строку. Поэтому вам нужно удалить запятые перед написанием строки CSV.

Сложная часть обработки CSV - это разбор приложений, что делает PHP и amp; Функции PEAR CSV ценны. По сути, вы ищете файл с разделителями-запятыми для столбцов и строки с разделителями строк для строк. Вот простая отправная точка:

<?php
$col_separator= ',';
$row_separator= "\n";

$a= array(
 array('my', 'values', 'are', 'awes,breakit,ome'),
 array('these', 'values', 'also', "rock\nAND\nROLL")
);

function encodeRow(array $a) {
 global $col_separator;
 global $row_separator;
 // Can't have the separators in the column data!
 $a2= array();
 foreach ($a as $v) {
  $a2[]= str_replace(array($col_separator, $row_separator), '', $v);
 }
 return implode($col_separator, $a2);
}

$output= array();
foreach ($a as $row) {
 $output[]= encodeRow($row);
}

echo(implode($row_separator, $output));

?>
0
ответ дан leepowers 27 August 2018 в 01:20
поделиться

работает с функцией chr ():

fputcsv($f,$array,',',chr(0));
11
ответ дан Michal Wrd 27 August 2018 в 01:20
поделиться
  • 1
    -1 не работает для меня – mkk 25 September 2013 в 11:48
  • 2
    Кажется, что в UTF-8 файлы работают неправильно – terox 12 June 2014 в 12:31
  • 3
    chr (0) создать null char, который отображается в utf8, как ^ @ – Mike 26 February 2015 в 20:27
  • 4
    Я сомневаюсь, что это хорошая идея. Вы на самом деле пишете "\0". В основном невидимый, пока он не вернется, чтобы укусить вас. – Jon Surrell 11 March 2015 в 16:12

fputcsv($file, $data, ';', chr(127));

4
ответ дан Raul Duran 27 August 2018 в 01:20
поделиться
  • 1
    Это был тот, который я искал. Спасибо m8! – Robin K 2 May 2018 в 15:26
  • 2
    Да, это правильный ответ. Работала отлично. спасибо – Mark 13 June 2018 в 05:39
  • 3
    На самом деле, chr (127) по-прежнему отображается как символ в файле, поэтому он не идеален. Черт – Mark 14 June 2018 в 06:41

chr(0) также работал для меня:

 fputcsv($fp, $aLine, $sDelimiter, chr(0));
0
ответ дан SHAZ 27 August 2018 в 01:20
поделиться
  • 1
    Я думаю, что это работает, потому что ваш редактор не показывает вам нулевой символ, но он все еще там – nickel715 13 September 2016 в 12:37
<?php       

$filename = "sample.csv";
$handle = fopen($filename, 'w+');
fputcsv($handle, ['column 1','column 2']);
$data = ['sample','data'];

fputs($handle, implode($data,',')."\n");

// or

fwrite($handle, implode($data,',')."\n");

fclose($handle);
$headers = array(
    'Content-Type' => 'text/csv',
);
1
ответ дан zeros-and-ones 27 August 2018 в 01:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: