В настоящее время вы присоединяетесь к своим фреймам данных следующим образом:
(((td1 + td2) + td3) + td4)
На каждом этапе вы объединяете огромный фрейм данных с небольшим фреймом данных, что приводит к копированию на каждом шаге и большому расходу памяти. Я бы предложил объединить их так:
(td1 + td2) + (td3 + td4)
Идея состоит в том, чтобы итеративно объединять пары примерно одинакового размера, пока не останется один результат. Вот прототип:
def pairwise_reduce(op, x):
while len(x) > 1:
v = [op(i, j) for i, j in zip(x[::2], x[1::2])]
if len(x) > 1 and len(x) % 2 == 1:
v[-1] = op(v[-1], x[-1])
x = v
return x[0]
result = pairwise_reduce(DataFrame.unionAll, df_list)
Вы увидите, как это имеет огромное значение для списков Python.
from functools import reduce
from operator import add
x = [[1, 2, 3], [4, 5, 6], [7, 8], [9, 10, 11, 12]] * 1000
%timeit sum(x, [])
%timeit reduce(add, x)
%timeit pairwise_reduce(add, x)
64.2 ms ± 606 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
66.3 ms ± 679 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
970 µs ± 9.02 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
sum(x, []) == reduce(add, x) == pairwise_reduce(add, x)
# True
Можно сделать это как это:
class Example {
private $__readOnly = 'hello world';
function __get($name) {
if($name === 'readOnly')
return $this->__readOnly;
user_error("Invalid property: " . __CLASS__ . "->$name");
}
function __set($name, $value) {
user_error("Can't set property: " . __CLASS__ . "->$name");
}
}
Только используйте это при реальной необходимости в нем - это медленнее, чем нормальный доступ свойства. Для PHP, лучше принимать политику только использования методов установщика изменить свойство с внешней стороны.
Class PropertyExample {
private $m_value;
public function Value() {
$args = func_get_args();
return $this->getSet($this->m_value, $args);
}
protected function _getSet(&$property, $args){
switch (sizeOf($args)){
case 0:
return $property;
case 1:
$property = $args[0];
break;
default:
$backtrace = debug_backtrace();
throw new Exception($backtrace[2]['function'] . ' accepts either 0 or 1 parameters');
}
}
}
Вот как я имею дело с получением / настройкой моих свойств, если вы хотите сделать Value () доступным только для чтения ... тогда вы просто просто сделаете это вместо этого:
return $this->m_value;
Где как функция Value () сейчас либо получит, либо установит.
Я вижу, вы уже получили свой ответ, но для тех, кто все еще ищет:
Просто объявите все переменные "только для чтения" как закрытые или защищенные и используйте волшебный метод __get () следующим образом:
/**
* This is used to fetch readonly variables, you can not read the registry
* instance reference through here.
*
* @param string $var
* @return bool|string|array
*/
public function __get($var)
{
return ($var != "instance" && isset($this->$var)) ? $this->$var : false;
}
Как видите, я также защитил переменную экземпляра $ this->, поскольку этот метод позволяет пользователям читать все объявленные переменные. Чтобы заблокировать несколько переменных, используйте массив с in_array ().
Но частные свойства, предоставляемые только с помощью __get (), не видны функциям, которые перечисляют элементы объекта - например, json_encode ().
Я регулярно передаю объекты PHP в Javascript с помощью json_encode ( ), поскольку это хороший способ передать сложные структуры с большим количеством данных, заполненных из базы данных. Я должен использовать общедоступные свойства в этих объектах, чтобы эти данные передавались в Javascript, который их использует, но это означает, что эти свойства должны быть общедоступными (и, следовательно, есть риск того, что другой программист не на той же длине волны (или, возможно, я после плохой ночи) мог бы изменить их напрямую). Если я сделаю их закрытыми и использую __get () и __set (), то json_encode () их не увидит.
Разве не было бы неплохо иметь ключевое слово доступности "только для чтения"?