Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/318.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在维护索引的同时,将字符串化列表列表转换为数据帧_Python_Pandas - Fatal编程技术网

Python 在维护索引的同时,将字符串化列表列表转换为数据帧

Python 在维护索引的同时,将字符串化列表列表转换为数据帧,python,pandas,Python,Pandas,我有以下来自API源的数据帧,我试图在不大量更改原始数据帧的情况下对数据进行争论(本质上不想做笛卡尔乘积) 键值度量告诉数组的顺序,我正在尝试以{Key:Value}的字典方式对数组进行排序,其中键是连接的键和度量字段,值是嵌套列表的-1索引 源数据是通过excel和MS Graph API提供的,我不认为它会改变,但可能会改变,所以我正在尝试提出一个动态解决方案 我的目标数据帧是: target_df = pd.DataFrame({'id' : [0,1,2],

我有以下来自API源的数据帧,我试图在不大量更改原始数据帧的情况下对数据进行争论(本质上不想做笛卡尔乘积)


度量
告诉数组的顺序,我正在尝试以{Key:Value}的字典方式对数组进行排序,其中键是连接的
度量
字段,值是嵌套列表的
-1
索引

源数据是通过excel和MS Graph API提供的,我不认为它会改变,但可能会改变,所以我正在尝试提出一个动态解决方案

我的目标数据帧是:

target_df = pd.DataFrame({'id' : [0,1,2],
                         'foo_bar' : [4,5,6],
                         'foo1_bar1' : [np.nan, np.nan,''],
                         'foo2_bar2' : [55.21, np.nan, 57.75]})

我自己的尝试是使用
ast
库中的literal_eval来获取第一个列表,该列表始终是
度量
列-将来可能会出现
度量
度量2
Value
字段-因此我希望保持事物的动态性

始终会有一个
字段

自己的尝试: 使用此方法,我替换了列表字符并用
拆分,
然后将结果转换为数据帧:

df['arr'].str.replace('\[|\]','').str.split(',',expand=True)

然而,在这之后,我还没有弄清楚方向,不知道我是否走错了方向?

我仍然不能完全确定我是否理解了问题的各个方面,但以下是我到目前为止所了解的

导入ast
作为pd进口熊猫
数据=[“['Key'、'Metric'、'Value']、['foo'、'bar'、'4']、['foo2'、'bar2'、'55.21']”,
“[['Key'、'Metric'、'Value']、['foo'、'bar'、'5']],
“[['Key'、'Metric'、'Value']、['foo'、'bar'、'6']、['foo1'、'bar1'、''、'foo2'、'bar2'、'57.75']]”
嵌套的_列表=[ast.literal_eval(elem)[1:]表示数据中的元素]
row_dicts=[{''''.join([key,metric]):key的值,metric,curr_list中的值}用于嵌套_list中的curr_list]
df=pd.数据帧(数据=行)
打印(df)
输出:

foo\u bar foo2\u bar2 foo1\u bar1
0455.21南
15楠楠
2       6     57.75          

nested\u list
row\u dicts
是列表理解,因为它使调试更容易,但您当然可以将它们转换为生成器表达式。

IIUC,您可以在每一行上循环并使用
literal\u eval
,创建数据帧,
设置索引
前两列和
转置
。然后
concat
加上重命名列,并创建列id:

from ast import literal_eval

df_target = pd.concat([pd.DataFrame.from_records(literal_eval(x)).drop(0).set_index([0,1]).T 
                       for x in df.arr.to_numpy()], 
                       ignore_index=True, 
                       keys=df.id) #to keep the ids
# rename the columns as wanted
df_target.columns = ['{}_{}'.format(*col) for col in df_target.columns]
# add the ids as a column
df_target = df_target.reset_index().rename(columns={'index':'id'})

print (df_target)
   id foo_bar foo1_bar1 foo2_bar2
0   0       4       NaN     55.21
1   1       5       NaN       NaN
2   2       6               57.75
尝试:

df2=df[“arr”].map(eval).apply(lambda x:pd.Series({f{el[0]}}{el[1]}):el[2]表示x[1:]}中的el)
df2[“id”]=df[“id”]
输出:

foo\u bar foo2\u bar2 foo1\u bar1 id
0455.21NAN0
1 5南南1
2       6     57.75             2

与实际子列表相比,键、值和度量字符串“无序”是否有任何原因?(我希望这足够清楚)@AMC-抱歉,拼写错误花了一段时间来阐述这个问题,经过了几次迭代。嗯,我还不确定我是否完全理解了这个问题。索引与此有什么关系?@AMC索引是原始数据帧,我基本上想在将数据摄入数据仓库之前,将这些列表分解为原始数据帧上的新列-简言之,我想保持原始形状。好的,接下来有几个不同的问题。如果你把这些列表作为数据帧,你知道从那里去哪里吗?启动cluster to test=)Ben这真的很好-我试图让它对我的目标数据集起作用,它有更多级别的嵌套列表,但结果总是出错-它把我推向了正确的方向,非常感谢您的帮助,并为没有正确地传达我的问题表示歉意。@DataNearior很高兴您找到了解决pb的方法:)@DataNearior我的目标数据集有更多级别的嵌套列表……这看起来很有希望,现在将进行测试。这也很好,但我的实际数据不是来自列表而是来自API@Datanovice不幸的是,你的帖子和你的评论却恰恰相反。您以什么格式获取数据?从接受的答案来看,您似乎只是想将现有列添加到新数据中?说到公认的答案,它使用了
eval()
,这是非常不安全的。我所说的列表是指变量
data
,它来自一个API调用,格式为列
arr
中的第一个数据帧,谢谢@我猜“API调用”是一种调用API并将结果转换为数据帧的方法?或者您正在创建数据帧?感谢这一点-非常好地使用了f字符串,我将其转换为一个函数,以添加更多的逻辑,但它很好。谢谢你,伙计。
print(target_df)

   id  foo_bar  foo1_bar1  foo2_bar2
0   0        4        NaN      55.21
1   1        5        NaN        NaN
2   2        6                 57.75
from ast import literal_eval

literal_eval(df['arr'][0])[0]
#['Key', 'Value', 'Metric']
df['arr'].str.replace('\[|\]','').str.split(',',expand=True)
from ast import literal_eval

df_target = pd.concat([pd.DataFrame.from_records(literal_eval(x)).drop(0).set_index([0,1]).T 
                       for x in df.arr.to_numpy()], 
                       ignore_index=True, 
                       keys=df.id) #to keep the ids
# rename the columns as wanted
df_target.columns = ['{}_{}'.format(*col) for col in df_target.columns]
# add the ids as a column
df_target = df_target.reset_index().rename(columns={'index':'id'})

print (df_target)
   id foo_bar foo1_bar1 foo2_bar2
0   0       4       NaN     55.21
1   1       5       NaN       NaN
2   2       6               57.75