0

私は仕事関連の XML ベースの API を調査しました。これは倉庫データから来ています。理想的には、パンダを使用して Python で分析を行いたいと考えています。

Aggregate(aggregate_dimension_value_list=[ DateAggregateDimensionValue(value=datetime.datetime(2013, 8, 28, 19, 30, tzinfo= UTC )) , None,  StringAggregateDimensionValue(value=u'VIRTUALLY_LABELED_CASE') ], quantity=127) ,  

Aggregate(aggregate_dimension_value_list=[ DateAggregateDimensionValue(value=datetime.datetime(2013, 8, 28, 19, 30, tzinfo= UTC )) ,  StringAggregateDimensionValue(value=u'PPTransMergeNonCon') ,  StringAggregateDimensionValue(value=u'PRIME_BIN_RANDOM_STOW') ], quantity=15)   

Aggregate(aggregate_dimension_value_list=[ DateAggregateDimensionValue(value=datetime.datetime(2013, 8, 27, 21, 0, tzinfo= UTC )) ,  StringAggregateDimensionValue(value=u'PPTransFRA1') ,  StringAggregateDimensionValue(value=u'PRIME_BIN_RANDOM_STOW') ], quantity=8) ,  

VIMで検索と置換を行った後、データは上記のストリームのようになります(Pythonでこれをスクリプト化できることはわかっています)。この奇妙なフォーマットを Pandas に取り込むにはどうすればよいですか? 理想的には、日時、文字列の集計ディメンション値、および数量が必要です。しかし、この解析が必要なデータには、多くの None があります。データフレームでは、いくつかの分析を行うのは簡単ですが、私はここで少し困惑しています (そして、n00b のように感じます)。

編集:これは、取得して解析したい、正規表現されておらず、置換されていないデータです。実際には XML ではないため、XML は機能しません。

[<DateAggregateDimensionValue(value=datetime.datetime(2013, 8, 26, 20, 30, tzinfo=<UTC
>))>, <StringAggregateDimensionValue(value=u'PPTransCGN1')>, <
StringAggregateDimensionValue(value=u'PRIME_BIN_RANDOM_STOW')>], quantity=992)>, <
StringAggregateDimensionValue(value=u'PPTransLEJ1')>, <StringAggregateDimensionValue(
value=u'PRIME_BIN_RANDOM_STOW')>], quantity=945)>, <Aggregate(
aggregate_dimension_value_list=[<DateAggregateDimensionValue(value=datetime.datetime(2013
, 8, 23, 19, 30, tzinfo=<UTC>))>, None, <StringAggregateDimensionValue(value=u'TOTE')>],
 quantity=87)>, <Aggregate(aggregate_dimension_value_list=[<DateAggregateDimensionValue(
value=datetime.datetime(2013, 8, 27, 17, 30, tzinfo=<UTC>))>, <
StringAggregateDimensionValue(value=u'PPTransMUC3')>, <StringAggregateDimensionValue(
value=u'TOTE')>], quantity=14)>, <Aggregate(aggregate_dimension_value_list=[<
DateAggregateDimensionValue(value=datetime.datetime(2013, 8, 27, 20, 30, tzinfo=<UTC
>))>, <StringAggregateDimensionValue(value=u'PPTransEUK5')>, <
StringAggregateDimensionValue(value=u'PRIME_BIN_RANDOM_STOW')>], quantity=339)>, <
Aggregate(aggregate_dimension_value_list=[<DateAggregateDimensionValue(value=datetime.
datetime(2013, 8, 26, 20, 30, tzinfo=<UTC>))>, <StringAggregateDimensionValue(value=u
'PPTransCGN1')>, <StringAggregateDimensionValue(value=u'TOTE')>], quantity=1731)>, <
Aggregate(aggregate_dimension_value_list=[<DateAggregateDimensionValue(value=datetime.
datetime(2013, 8, 26, 19, 30, tzinfo=<UTC>))>, <StringAggregateDimensionValue(value=u
'PPTransEUK5')>, quantity=444)>, <Aggregate(aggregate_dimension_value_list=[<
DateAggregateDimensionValue(value=datetime.datetime(2013, 8, 26, 19, 30, tzinfo=<UTC
>))>, <StringAggregateDimensionValue(value=u'PPTransEUK5')>, <
StringAggregateDimensionValue(value=u'TOTE')>], quantity=28)>, <Aggregate(
aggregate_dimension_value_list=[<DateAggregateDimensionValue(value=datetime.datetime(2013
, 8, 28, 19, 30, tzinfo=<UTC>))>, <StringAggregateDimensionValue(value=u'PPTransORY1')>,
 <StringAggregateDimensionValue(value=u'PRIME_BIN_RANDOM_STOW')>], quantity=69)>, <
Aggregate(aggregate_dimension_value_list=<Aggregate(aggregate_dimension_value_list=[<
DateAggregateDimensionValue(value=datetime.datetime(2013, 8, 26, 19, 30, tzinfo=<UTC
>))>, <StringAggregateDimensionValue(value=u'PPTransMAD4')>, <
StringAggregateDimensionValue(value=u'PRIME_BIN_RANDOM_STOW')>], quantity=47)>, <
Aggregate(aggregate_dimension_value_list=[<DateAggregateDimensionValue(value=datetime.
datetime(2013, 8, 26, 21, 0, tzinfo=<UTC>))>, None, None], quantity=78)>
4

2 に答える 2

1

パーサーのラインに沿ってもっと何かを好む場合は、問題に対する pyparsing stab を次に示します。

from pyparsing import Suppress,QuotedString,Word,alphas,nums,alphanums,Keyword,Optional
import datetime

# define UTC timezone for sake of eval
if hasattr(datetime,"timezone"):
    UTC = datetime.timezone(datetime.timedelta(0),"UTC")
else:
    UTC = None

_ = Suppress
evaltokens = lambda s,l,t: eval(''.join(t))

timevalue = 'datetime.datetime' + QuotedString('(', endQuoteChar=')', unquoteResults=False)
timevalue.setParseAction(evaltokens)

strvalue = 'u' + QuotedString("'", unquoteResults=False)
strvalue.setParseAction(evaltokens)

nonevalue = Keyword("None").setParseAction(lambda s,l,t: [None])
intvalue = Word(nums).setParseAction(lambda s,l,t: int(t[0]))

COMMA = Optional(_(","))

valuedexpr = lambda expr: (Word(alphas) + "(" + "value" + "=" + expr + ")").setParseAction(lambda t: t[4])

lineexpr = (_("Aggregate(aggregate_dimension_value_list=[") +
            valuedexpr(timevalue)("timestamp") + COMMA +
            (nonevalue | valuedexpr(strvalue))("s1") + COMMA +
            (nonevalue | valuedexpr(strvalue))("s2") + COMMA +
        "]" + COMMA +
        "quantity=" + intvalue("qty"))

lineexpr.searchString各 Aggregate からデータを引き出すために使用します。

for data in lineexpr.searchString(sample):
    print data.dump()
    print data.qty
    print

与える:

[datetime.datetime(2013, 8, 28, 19, 30), None, u'VIRTUALLY_LABELED_CASE', ']', 'quantity=', 127]
- qty: 127
- s1: None
- s2: VIRTUALLY_LABELED_CASE
- timestamp: 2013-08-28 19:30:00
127

[datetime.datetime(2013, 8, 28, 19, 30), u'PPTransMergeNonCon', u'PRIME_BIN_RANDOM_STOW', ']', 'quantity=', 15]
- qty: 15
- s1: PPTransMergeNonCon
- s2: PRIME_BIN_RANDOM_STOW
- timestamp: 2013-08-28 19:30:00
15

[datetime.datetime(2013, 8, 27, 21, 0), u'PPTransFRA1', u'PRIME_BIN_RANDOM_STOW', ']', 'quantity=', 8]
- qty: 8
- s1: PPTransFRA1
- s2: PRIME_BIN_RANDOM_STOW
- timestamp: 2013-08-27 21:00:00
8

dump()は、利用可能なすべての名前付き結果値を表示します - を使用して数量属性に直接アクセスする方法に注意してくださいdata.qty。これは、 の結果名「qty」の定義で設定されています"quantity=" + intvalue("qty")timestamps1、およびs2同様にアクセスできます。(これにはまだ少しevaling があります。それをきれいにすることは、読者の課題として残されています。)

編集:

元の生の XML のようなものを処理するために、変更された pyparsing パーサーを次に示します。変更は非常に小さなものでした:

from pyparsing import Suppress,QuotedString,Word,alphas,nums,alphanums,Keyword,Optional, ungroup
import datetime

# define UTC timezone for sake of eval
if hasattr(datetime,"timezone"):
    UTC = datetime.timezone(datetime.timedelta(0),"UTC")
else:
    UTC = None

_ = Suppress
evaltokens = lambda s,l,t: eval(''.join(t))

timevalue = 'datetime.datetime' + QuotedString('(', endQuoteChar=')', unquoteResults=False)
replUTC = lambda s,l,t: ''.join(t).replace("< UTC>","UTC").replace("<UTC >","UTC").replace("<UTC>","UTC")
timevalue.setParseAction(replUTC, evaltokens)

strvalue = 'u' + QuotedString("'", unquoteResults=False)
strvalue.setParseAction(evaltokens)

nonevalue = Keyword("None").setParseAction(lambda s,l,t: [None])
intvalue = Word(nums).setParseAction(lambda s,l,t: int(t[0]))

COMMA = Optional(_(","))
LT,GT,LPAR,RPAR,LBRACK,RBRACK = map(Suppress,"<>()[]")

#~ valuedexpr = lambda expr: (Word(alphas) + "(" + "value" + "=" + expr + ")").setParseAction(lambda t: t[4])
valuedexpr = lambda expr: ungroup(LT + (Word(alphas) + "(" + "value" + "=" + expr("value") + ")" + GT).setParseAction(lambda t: t.value))

#~ lineexpr = (_("Aggregate(aggregate_dimension_value_list=[") +
            #~ valuedexpr(timevalue)("timestamp") + COMMA +
            #~ (nonevalue | valuedexpr(strvalue))("s1") + COMMA +
            #~ (nonevalue | valuedexpr(strvalue))("s2") + COMMA +
        #~ "]" + COMMA +
        #~ "quantity=" + intvalue("qty"))

lineexpr = (LT + "Aggregate" + LPAR + "aggregate_dimension_value_list" + "=" + LBRACK +
            valuedexpr(timevalue)("timestamp") + COMMA +
            (nonevalue | valuedexpr(strvalue))("s1") + COMMA +
            (nonevalue | valuedexpr(strvalue))("s2") + 
        RBRACK + COMMA +
        "quantity=" + intvalue("qty") + RPAR + GT)

貼り付けたテキスト (一部は形式が正しくありません) から、次のようになります。

['Aggregate', 'aggregate_dimension_value_list', '=', datetime.datetime(2013, 8, 26, 20, 30), u'PPTransCGN1', u'PRIME_BIN_RANDOM_STOW', 'quantity=', 992]
- qty: 992
- s1: PPTransCGN1
- s2: PRIME_BIN_RANDOM_STOW
- timestamp: 2013-08-26 20:30:00
992

['Aggregate', 'aggregate_dimension_value_list', '=', datetime.datetime(2013, 8, 23, 19, 30), None, u'TOTE', 'quantity=', 87]
- qty: 87
- s1: None
- s2: TOTE
- timestamp: 2013-08-23 19:30:00
87

['Aggregate', 'aggregate_dimension_value_list', '=', datetime.datetime(2013, 8, 27, 17, 30), u'PPTransMUC3', u'TOTE', 'quantity=', 14]
- qty: 14
- s1: PPTransMUC3
- s2: TOTE
- timestamp: 2013-08-27 17:30:00
14

['Aggregate', 'aggregate_dimension_value_list', '=', datetime.datetime(2013, 8, 27, 20, 30), u'PPTransEUK5', u'PRIME_BIN_RANDOM_STOW', 'quantity=', 339]
- qty: 339
- s1: PPTransEUK5
- s2: PRIME_BIN_RANDOM_STOW
- timestamp: 2013-08-27 20:30:00
339

['Aggregate', 'aggregate_dimension_value_list', '=', datetime.datetime(2013, 8, 26, 20, 30), u'PPTransCGN1', u'TOTE', 'quantity=', 1731]
- qty: 1731
- s1: PPTransCGN1
- s2: TOTE
- timestamp: 2013-08-26 20:30:00
1731

['Aggregate', 'aggregate_dimension_value_list', '=', datetime.datetime(2013, 8, 26, 19, 30), u'PPTransEUK5', u'TOTE', 'quantity=', 28]
- qty: 28
- s1: PPTransEUK5
- s2: TOTE
- timestamp: 2013-08-26 19:30:00
28

['Aggregate', 'aggregate_dimension_value_list', '=', datetime.datetime(2013, 8, 28, 19, 30), u'PPTransORY1', u'PRIME_BIN_RANDOM_STOW', 'quantity=', 69]
- qty: 69
- s1: PPTransORY1
- s2: PRIME_BIN_RANDOM_STOW
- timestamp: 2013-08-28 19:30:00
69

['Aggregate', 'aggregate_dimension_value_list', '=', datetime.datetime(2013, 8, 26, 19, 30), u'PPTransMAD4', u'PRIME_BIN_RANDOM_STOW', 'quantity=', 47]
- qty: 47
- s1: PPTransMAD4
- s2: PRIME_BIN_RANDOM_STOW
- timestamp: 2013-08-26 19:30:00
47

['Aggregate', 'aggregate_dimension_value_list', '=', datetime.datetime(2013, 8, 26, 21, 0), None, None, 'quantity=', 78]
- qty: 78
- s1: None
- s2: None
- timestamp: 2013-08-26 21:00:00
78
于 2013-08-26T12:26:19.693 に答える
0

AggregateDateAggregateDimensionValue、およびの最小クラスを定義しStringAggregateDimensionValue、次にeval各行を順番に定義できます。

import datetime

# define UTC timezone for sake of eval
if hasattr(datetime,"timezone"):
    UTC = datetime.timezone(datetime.timedelta(0),"UTC")
else:
    UTC = None

# define minimal classes to eval initializers
class AggregateDimensionValue(object):
    def __init__(self, value):
        self.value = value
class StringAggregateDimensionValue(AggregateDimensionValue): pass
class DateAggregateDimensionValue(AggregateDimensionValue): pass
class Aggregate(object):
    def __init__(self, aggregate_dimension_value_list, quantity):
        self.timestamp, self.s1, self.s2 = aggregate_dimension_value_list
        # pull values out of parsed "aggregate" instances
        self.timestamp = self.timestamp.value
        if self.s1 is not None:
            self.s1 = self.s1.value
        if self.s2 is not None:
            self.s2 = self.s2.value
        self.quantity = quantity

これらの最小限のクラスをeval入力文字列に使用します。

for line in sample.splitlines():
    if not line.strip():
        continue
    obj = eval(line.strip(' ,'))
    print obj.__dict__

与えます:

{'timestamp': datetime.datetime(2013, 8, 28, 19, 30), 's1': None, 'quantity': 127, 's2': u'VIRTUALLY_LABELED_CASE'}
{'timestamp': datetime.datetime(2013, 8, 28, 19, 30), 's1': u'PPTransMergeNonCon', 'quantity': 15, 's2': u'PRIME_BIN_RANDOM_STOW'}
{'timestamp': datetime.datetime(2013, 8, 27, 21, 0), 's1': u'PPTransFRA1', 'quantity': 8, 's2': u'PRIME_BIN_RANDOM_STOW'}

もちろん、これにはeval、悪意のあるコードが挿入される可能性に注意するなど、 の使用に関する通常の注意事項がすべて含まれています。しかし、あなたはすでにこの入力ファイルを自分で制御しているのではないかと思います。そのため、自分の悪意のあるコードを挿入したとしても、責任を負うのは自分自身だけです。

于 2013-08-26T12:17:25.530 に答える