选择 DataFrame 中的元素

use*_*597 2 dataframe python-3.x pandas

我有一个没有包含信息字符串的列标题的数据框。我想根据每个单元格中的子字符串选择单元格中的部分值,并将这些元素包含在列表中。我发现列出答案的示例引用了数据帧中的单个(命名)列,并且可以轻松地应用 loc/iloc 来获取数据帧的 str 属性

数据框如下所示:

0 A[3,5] A[6,7] C[3,9]
1 B[2,9] A[2,1] B[3,7]
2 B[5,6]   
Run Code Online (Sandbox Code Playgroud)

从数据框中,我想提取括号中包含的所有坐标,这些坐标在列表中列为 A (作为字符串)。结果列表应该是:

[3,5, 6,7, 2,1]
Run Code Online (Sandbox Code Playgroud)

我已从 csv 读取数据并将其包含在数据框中。我尝试了两种方法:首先,构建一个具有相同维度的数据框,并在存在字母 A 的地方用 1 填充它。

其次,我试图在数据框中找到字符串“A”出现的位置,并一次性提取括号之间的部分。在这两种方法中,我都试图使用 loc/iloc 来引用数据帧的列,但得到一个AttributeError: 'DataFrame' object has no attribute 'str'. 我的思考方式是否正确,或者是否有更有效的方式来解决我的问题?

更新:我已经能够将数据帧堆叠成一个系列,并且只剩下包含“A”的值。现在我希望根据括号之间的子字符串来隔离坐标。下面代码的最后一行产生了一个TypeError: 'Series' objects are mutable, thus they cannot be hashed. 如何检索括号中的子字符串?

df = pd.read_csv("FILE.csv", header = None)
df = df.fillna('')

s = df.stack()
s = s[s.str.contains("A")]

s = s[s.str.find("["):s.str.rfind("]")]
Run Code Online (Sandbox Code Playgroud)

jez*_*ael 5

错误意味着没有一列,而是更多的列。因此,如果所有数据都在多列中,请DataFrame.stack在第一步中使用,然后通过Series.str.replace以下方式处理数据:

df = pd.read_csv("FILE.csv", header = None)

s = df.stack()

L = s[s.str.contains("A")].str.replace('[A\[\]]', '').tolist()
print (L)
['3,5', '6,7', '2,1']
Run Code Online (Sandbox Code Playgroud)

最后,如果想要成对的整数,可以使用列表理解:

L1 = [[int(y) for y in x.split(',')] for x in L]
print (L1)
[[3, 5], [6, 7], [2, 1]]
Run Code Online (Sandbox Code Playgroud)

或者@Vishnudev 的解决方案pd.eval更安全,例如eval

L2 = s[s.str.contains("A")].str.replace('[A]', '').map(pd.eval).explode().tolist()
print (L2)
[3, 5, 6, 7, 2, 1]
Run Code Online (Sandbox Code Playgroud)

另一个想法Series.str.extractall

L2 = s[s.str.contains("A")].str.extractall('(\d+)')[0].astype(int).tolist()
print (L2)
[3, 5, 6, 7, 2, 1]
Run Code Online (Sandbox Code Playgroud)

编辑:

在您的解决方案中,需要通过以下方式删除fillna可能删除的缺失值stack

print (df)
        0       1       2
0  A[3,5]  A[6,7]  C[3,9]
1  B[2,9]  A[2,1]  B[3,7]
2  B[5,6]     NaN     NaN

s = df.stack()
print (s)
0  0    A[3,5]
   1    A[6,7]
   2    C[3,9]
1  0    B[2,9]
   1    A[2,1]
   2    B[3,7]
2  0    B[5,6]
dtype: object

s = s[s.str.contains("A")]
print (s)
0  0    A[3,5]
   1    A[6,7]
1  1    A[2,1]
dtype: object
Run Code Online (Sandbox Code Playgroud)

最后一个值之间[]的更好用Series.str.extract

s = s.str.extract(r"\[(.*?)\]", expand=False)
print (s)
0  0    3,5
   1    6,7
1  1    2,1
dtype: object
Run Code Online (Sandbox Code Playgroud)

您的解决方案可以通过列表理解来实现:

a = [x[x.find("[")+1:x.rfind("]")] for x in s]
print (a)
['3,5', '6,7', '2,1']
Run Code Online (Sandbox Code Playgroud)