我在csv文件中有以下数据:
from StringIO import StringIO
import pandas as pd
the_data = """
ABC,2016-6-9 0:00,95,{'//Purple': [115L], '//Yellow': [403L], '//Blue': [16L], '//White-XYZ': [0L]}
ABC,2016-6-10 0:00,0,{'//Purple': [219L], '//Yellow': [381L], '//Blue': [90L], '//White-XYZ': [0L]}
ABC,2016-6-11 0:00,0,{'//Purple': [817L], '//Yellow': [21L], '//Blue': [31L], '//White-XYZ': [0L]}
ABC,2016-6-12 0:00,0,{'//Purple': [80L], '//Yellow': [2011L], '//Blue': [8888L], '//White-XYZ': [0L]}
ABC,2016-6-13 0:00,0,{'//Purple': [32L], '//Yellow': [15L], '//Blue': [4L], '//White-XYZ': [0L]}
DEF,2016-6-16 0:00,0,{'//Purple': [32L], '//Black': [15L], '//Pink': [4L], '//NPO-Green': [3L]}
DEF,2016-6-17 0:00,0,{'//Purple': [32L], '//Black': [15L], '//Pink': [4L], '//NPO-Green': [0L]}
DEF,2016-6-18 0:00,0,{'//Purple': [32L], '//Black': [15L], '//Pink': [4L], '//NPO-Green': [7L]}
DEF,2016-6-19 0:00,0,{'//Purple': [32L], '//Black': [15L], '//Pink': [4L], '//NPO-Green': [14L]}
DEF,2016-6-20 0:00,0,{'//Purple': [32L], '//Black': [15L], '//Pink': [4L], '//NPO-Green': [21L]}
"""
我将数据读入Pandas数据框,如下所示:
df = pd.read_csv(StringIO(the_data), sep=',', header=None)
'公司'和'日期'字段永远不会改变。
然而,&#39>键'大括号内(例如"//PurpleCar"
,"//YellowCar"
,"//BlueCar"
,"//WhiteCar"
,"//BlackCar"
,"//BlackCar"
和"NPO-GreenCar"
)不静态。他们可以(并且会)经常改变。
(注意:我输出字典的另一个脚本'创建'这个文本文件,因此这个数据结构)
我希望数据框显示如下,以便我可以使用Matplotlib创建可视化:
Company Date Purple Yellow Blue White-XYZ Black Pink NPO-Green
0 ABC 2016-6-9 115 403 16 0 0 0 0
1 ABC 2016-6-10 219 381 90 0 0 0 0
2 ABC 2016-6-11 817 21 31 0 0 0 0
3 ABC 2016-6-12 80 2011 8888 0 0 0 0
4 ABC 2016-6-13 32 15 4 0 0 0 0
5 DEF 2016-6-16 32 0 0 0 15 4 3
6 DEF 2016-6-17 32 0 0 0 15 4 0
7 DEF 2016-6-18 32 0 0 0 15 4 7
8 DEF 2016-6-19 32 0 0 0 15 4 14
9 DEF 2016-6-20 32 0 0 0 15 4 21
我面临的问题是:
a)移动'键'值最多为列标题
b)允许'键#39;值是动态的(同样,它们可以并且将会改变) c)删除方括号('['
和']'
)
d)删除双斜杠('//'
)
积分' c'' d'并且' e'以上问题可以通过以下问题解决(相关):
它的要点' a'和' b'那些我正在努力的人。
有没有人看到解决这些问题的方法?
谢谢!
*更新*
最初发布的数据有一个小错误。这是数据:
the_data = """
ABC,2016-6-9 0:00,95,"{'//Purple': [115L], '//Yellow': [403L], '//Blue': [16L], '//White-XYZ': [0L]}"
ABC,2016-6-10 0:00,0,"{'//Purple': [219L], '//Yellow': [381L], '//Blue': [90L], '//White-XYZ': [0L]}"
ABC,2016-6-11 0:00,0,"{'//Purple': [817L], '//Yellow': [21L], '//Blue': [31L], '//White-XYZ': [0L]}"
ABC,2016-6-12 0:00,0,"{'//Purple': [80L], '//Yellow': [2011L], '//Blue': [8888L], '//White-XYZ': [0L]}"
ABC,2016-6-13 0:00,0,"{'//Purple': [32L], '//Yellow': [15L], '//Blue': [4L], '//White-XYZ': [0L]}"
DEF,2016-6-16 0:00,0,"{'//Purple': [32L], '//Black': [15L], '//Pink': [4L], '//NPO-Green': [3L]}"
DEF,2016-6-17 0:00,0,"{'//Purple': [32L], '//Black': [15L], '//Pink': [4L], '//NPO-Green': [0L]}"
DEF,2016-6-18 0:00,0,"{'//Purple': [32L], '//Black': [15L], '//Pink': [4L], '//NPO-Green': [7L]}"
DEF,2016-6-19 0:00,0,"{'//Purple': [32L], '//Black': [15L], '//Pink': [4L], '//NPO-Green': [14L]}"
DEF,2016-6-20 0:00,0,"{'//Purple': [32L], '//Black': [15L], '//Pink': [4L], '//NPO-Green': [21L]}"
"""
此数据与原始数据之间的差异是在开始大括号((")
)之前和结束大括号("{"
之后)的撇号"}"
。
答案 0 :(得分:0)
我真的不认为这只大熊猫可以为你做很多事。你的数据非常迟钝,在我看来最好用正则表达式来处理。这是我的解决方案:
import re
static_cols = []
dynamic_cols = []
for line in the_data.splitlines():
if line == '':
continue
# deal with static columns
x = line.split(',')
company, date, other = x[0:3]
keys = ['Company', 'Date', 'Other']
values = [company, date, other]
d = {i: j for i, j in zip(keys, values)}
static_cols.append(d)
# deal with dynamic columns
keys = re.findall(r'(?<=//)[^\']*', line)
values = re.findall(r'\d+(?=L)', line)
d = {i: j for i, j in zip(keys, values)}
dynamic_cols.append(d)
df1 = pd.DataFrame(static_cols)
df2 = pd.DataFrame(dynamic_cols)
df = pd.concat([df1, df2], axis=1)
输出:
此外,在我不确定如何处理的日期之后,您的数据有一个额外的列,所以我只称它为'其他'。它不包含在您的输出中,因此您可以根据需要轻松删除它。
答案 1 :(得分:0)
考虑使用ast.literal_eval()
将字典列值转换为Python字典,然后将它们作为单独的数据帧投射,以便与原始数据帧进行最终合并:
from io import StringIO
import pandas as pd
import ast
...
df = pd.read_csv(StringIO(the_data), header=None,
names=['Company', 'Date', 'Value', 'Dicts'])
dfList = []
for i in df['Dicts'].tolist():
result = ast.literal_eval(i.replace('L]', ']'))
result = {k.replace('//',''):v for k,v in result.items()}
temp = pd.DataFrame(result)
dfList.append(temp)
dictdf = pd.concat(dfList).reset_index(drop=True)
df = pd.merge(df, dictdf, left_index=True, right_index=True).drop(['Dicts'], axis=1)
print(df)
# Company Date Value Black Blue NPO-Green Pink Purple White-XYZ Yellow
# 0 ABC 2016-6-9 0:00 95 NaN 16.0 NaN NaN 115 0.0 403.0
# 1 ABC 2016-6-10 0:00 0 NaN 90.0 NaN NaN 219 0.0 381.0
# 2 ABC 2016-6-11 0:00 0 NaN 31.0 NaN NaN 817 0.0 21.0
# 3 ABC 2016-6-12 0:00 0 NaN 8888.0 NaN NaN 80 0.0 2011.0
# 4 ABC 2016-6-13 0:00 0 NaN 4.0 NaN NaN 32 0.0 15.0
# 5 DEF 2016-6-16 0:00 0 15.0 NaN 3.0 4.0 32 NaN NaN
# 6 DEF 2016-6-17 0:00 0 15.0 NaN 0.0 4.0 32 NaN NaN
# 7 DEF 2016-6-18 0:00 0 15.0 NaN 7.0 4.0 32 NaN NaN
# 8 DEF 2016-6-19 0:00 0 15.0 NaN 14.0 4.0 32 NaN NaN
# 9 DEF 2016-6-20 0:00 0 15.0 NaN 21.0 4.0 32 NaN NaN