Это невозможно, только вы можете определить словарь с ключами для функций и список для имен столбцов, а затем поменять местами ключи со значениями в цикле:
data_stores = pd.DataFrame({'store': [1, 1, 2, 2],
'item1': [45, 200, 20, 300],
'item2': [50, 300, 17, 350],
'item3': [53, 250, 21, 400]})
print (data_stores)
store item1 item2 item3
0 1 45 50 53
1 1 200 300 250
2 2 20 17 21
3 2 300 350 400
d = {'mean':'item1', 'sum' : ['item2', 'item3']}
out = {}
for k, v in d.items():
if isinstance(v, list):
for x in v:
out[x] = k
else:
out[v] = k
print (out)
{'item1': 'mean', 'item2': 'sum', 'item3': 'sum'}
data_stores_total = data_stores.groupby('store', as_index=False).agg(out)
print (data_stores_total)
store item1 item2 item3
0 1 122.5 350 303
1 2 160.0 367 421
Или:
d = {'mean':['item1'], 'sum' : ['item2', 'item3']}
d1 = {k: oldk for oldk, oldv in d.items() for k in oldv}
print (d1)
{'item1': 'mean', 'item2': 'sum', 'item3': 'sum'}
data_stores_total = data_stores.groupby('store', as_index=False).agg(d1)
print (data_stores_total)
store item1 item2 item3
0 1 122.5 350 303
1 2 160.0 367 421
[ 118] РЕДАКТИРОВАТЬ:
Если вы хотите агрегировать все столбцы без нескольких с помощью одной и той же функции агрегирования, вы можете создать словарь по всем столбцам с фильтрацией по списку с помощью difference
, а затем добавить ключ отсутствующих пар : значение для столбца: агрегатная функция:
out = dict.fromkeys(data_stores.columns.difference(['store','item1']), 'sum')
out['item1'] = 'mean'
print (out)
{'item2': 'sum', 'item3': 'sum', 'item1': 'mean'}
data_stores_total = data_stores.groupby('store', as_index=False).agg(out)
print (data_stores_total)
store item2 item3 item1
0 1 350 303 122.5
1 2 367 421 160.0
Вы также можете передать пользовательскую функцию, работающую с этим столбцом:
def func(x):
return x.sum() / x.mean()
out = dict.fromkeys(data_stores.columns.difference(['store','item1']), 'sum')
out['item1'] = func
print (out)
{'item2': 'sum', 'item3': 'sum', 'item1': }
data_stores_total = data_stores.groupby('store', as_index=False).agg(out)
print (data_stores_total)
store item2 item3 item1
0 1 350 303 2
1 2 367 421 2
Это - один из самых интересных вопросов, которые я видел! Я соглашаюсь с некоторыми из других сообщений, что рендеринг к битовому массиву и затем анализ битового массива будут наиболее надежным решением. Для простого PDFs вот более быстрое, но меньше полного подхода.
, Мое решение ниже делает № 1 и половину № 2. Другая половина № 2 должна была бы добиться пользовательского цвета, который вовлекает поиск записей / ColorSpace в страницу, и декодирование их - связываются со мной офлайн, если это интересно Вам, поскольку это очень выполнимо, но не за 5 минут.
Сначала основная программа:
use CAM::PDF;
my $infile = shift;
my $pdf = CAM::PDF->new($infile);
PAGE:
for my $p (1 .. $pdf->numPages) {
my $tree = $pdf->getPageContentTree($p);
if (!$tree) {
print "Failed to parse page $p\n";
next PAGE;
}
my $colors = $tree->traverse('My::Renderer::FindColors')->{colors};
my $uncertain = 0;
for my $color (@{$colors}) {
my ($name, @rest) = @{$color};
if ($name eq 'g') {
} elsif ($name eq 'rgb') {
my ($r, $g, $b) = @rest;
if ($r != $g || $r != $b) {
print "Page $p is color\n";
next PAGE;
}
} elsif ($name eq 'cmyk') {
my ($c, $m, $y, $k) = @rest;
if ($c != 0 || $m != 0 || $y != 0) {
print "Page $p is color\n";
next PAGE;
}
} else {
$uncertain = $name;
}
}
if ($uncertain) {
print "Page $p has user-defined color ($uncertain), needs more investigation\n";
} else {
print "Page $p is grayscale\n";
}
}
И затем вот рендерер помощника, который обрабатывает цветные директивы на каждой странице:
package My::Renderer::FindColors;
sub new {
my $pkg = shift;
return bless { colors => [] }, $pkg;
}
sub clone {
my $self = shift;
my $pkg = ref $self;
return bless { colors => $self->{colors}, cs => $self->{cs}, CS => $self->{CS} }, $pkg;
}
sub rg {
my ($self, $r, $g, $b) = @_;
push @{$self->{colors}}, ['rgb', $r, $g, $b];
}
sub g {
my ($self, $gray) = @_;
push @{$self->{colors}}, ['rgb', $gray, $gray, $gray];
}
sub k {
my ($self, $c, $m, $y, $k) = @_;
push @{$self->{colors}}, ['cmyk', $c, $m, $y, $k];
}
sub cs {
my ($self, $name) = @_;
$self->{cs} = $name;
}
sub cs {
my ($self, $name) = @_;
$self->{CS} = $name;
}
sub _sc {
my ($self, $cs, @rest) = @_;
return if !$cs; # syntax error
if ($cs eq 'DeviceRGB') { $self->rg(@rest); }
elsif ($cs eq 'DeviceGray') { $self->g(@rest); }
elsif ($cs eq 'DeviceCMYK') { $self->k(@rest); }
else { push @{$self->{colors}}, [$cs, @rest]; }
}
sub sc {
my ($self, @rest) = @_;
$self->_sc($self->{cs}, @rest);
}
sub SC {
my ($self, @rest) = @_;
$self->_sc($self->{CS}, @rest);
}
sub scn { sc(@_); }
sub SCN { SC(@_); }
sub RG { rg(@_); }
sub G { g(@_); }
sub K { k(@_); }
ImageMagick имеет некоторые встроенные методы для сравнения изображения.
http://www.imagemagick.org/Usage/compare/#type_general
существует некоторые API Perl для ImageMagick, поэтому возможно, при умном объединении их с PDF к Преобразователю изображения, можно найти способ сделать черный & белый тест.
Я попытался бы сделать это как этот, хотя могли бы быть другие более легкие решения, и мне любопытно услышать их, я просто хочу дать ему попытку:
Для количества страницы, можно, вероятно, перевести что без слишком большого усилия к Perl. Это - в основном regex. Это также , сказал что:
r" (/Тип) \s? (/Page) [/> \s]"
просто необходимо рассчитать, сколько раз это регулярное выражение происходит в файле PDF минус времена, Вы находите строку "<>" (пустые возрасты, которые не представляются).
Для извлечения изображения можно использовать ImageMagick, чтобы сделать это . Или см. этот вопрос .
Наконец, чтобы добраться, черно ли это и бело, это зависит, если Вы имеете в виду буквально черный и белый или полутоновый. Для черного цвета и белого цвета, Вы должны только иметь, ну, в общем, черный и белый во всем изображении. Если Вы хотите видеть шкалу полутонов, теперь, это - действительно не моя специальность, но я предполагаю, что Вы видели, ли средние числа красного, зеленого и синего цвета друг близко к другу или если исходное изображение и шкала полутонов преобразовала , каждый друг близко к другу.
Hope это дает некоторые подсказки, чтобы помочь Вам пойти далее.