Это не ответ на вопрос OP, а пример с игрушкой, чтобы проиллюстрировать ответ @ShikharDua, над которым я нашел очень полезным.
Хотя этот фрагмент тривиален, в фактических данных у меня было 1000 строк и много столбцов, и я хотел иметь возможность группировать по разным столбцам, а затем выполнять статистику ниже для более чем одного такета колонка. Таким образом, надежный метод построения кадра данных по одной строке за раз был большим удобством. Спасибо @ShikharDua!
import pandas as pd
BaseData = pd.DataFrame({ 'Customer' : ['Acme','Mega','Acme','Acme','Mega','Acme'],
'Territory' : ['West','East','South','West','East','South'],
'Product' : ['Econ','Luxe','Econ','Std','Std','Econ']})
BaseData
columns = ['Customer','Num Unique Products', 'List Unique Products']
rows_list=[]
for name, group in BaseData.groupby('Customer'):
RecordtoAdd={} #initialise an empty dict
RecordtoAdd.update({'Customer' : name}) #
RecordtoAdd.update({'Num Unique Products' : len(pd.unique(group['Product']))})
RecordtoAdd.update({'List Unique Products' : pd.unique(group['Product'])})
rows_list.append(RecordtoAdd)
AnalysedData = pd.DataFrame(rows_list)
print('Base Data : \n',BaseData,'\n\n Analysed Data : \n',AnalysedData)
Объявление %union
изменяет тип yylval
.
Руководство bison
объясняет :
В обычном (нерентабельный) парсер, семантическое значение токена должно храниться в глобальной переменной
yylval
. Когда вы используете только один тип данных для семантических значений,yylval
имеет этот тип. Таким образом, если типint
(по умолчанию), вы можете записать это вyylex
:... yylval = value; /* Put value onto Bison stack. */ return INT; /* Return the type of the token. */ ...
Когда вы используете несколько типов данных, тип
yylval
является объединением сделанные из объявления%union
(см. раздел «Коллекция типов значений»). Поэтому, когда вы сохраняете значение токена, вы должны использовать правильный член объединения. Если объявление%union
выглядит так:%union { int intval; double val; symrec *tptr; }
, тогда код в
yylex
может выглядеть следующим образом:blockquote>... yylval.intval = value; /* Put value onto Bison stack. */ return INT; /* Return the type of the token. */ ...
Цель union
- разрешить сохранение объектов другого типа в узлах, испускаемых flex.
Чтобы лучше объяснить, вы можете иметь, например:
%union
{
int intValue;
float floatValue;
char *stringValue;
}
в .y
, если вы хотите обеспечить базовую поддержку типов int
, float
и string
. Что вы можете сделать с этим?
Две вещи:
Во-первых, вы можете автоматически устанавливать правильные значения при создании токенов. Подумайте о файле .l
предыдущего примера, вы можете:
[a-zA-Z][a-zA-Z0-9]* {
yylval.stringValue = strdup(yytext);
return IDENTIFIER;
}
[0-9]+ {
yylval.intValue = atoi(yytext);
return INTEGER;
}
[0-9]*\.[0-9]+"f"? {
yylval.floatValue = new atof(yytext);
return FLOAT;
}
Кроме того, вы можете использовать значение непосредственно в вашей грамматике flex :
nexp: nexp '+' nexp { $<floatValue>$ = $<floatValue>1 + $<floatValue>3 }
Наконец, если вы планируете использовать дерево синтаксиса ООП, вы можете определить объединение как
%union
{
class ASTNode *node;
}
, в котором ASTNode
является классом предков любого типа синтаксического узла.
#define YYSTYPE class ASTNode *
(если память служит).
– Chris Lutz
6 December 2009 в 04:00