Вызов статических методов в Java требует указания точного типа.
Обратите внимание, что этот подход не универсален для всех языков: например, вы можете переопределить методы класса в Objective-C, а какао-каркасы Apple хорошо используют этот механизм для настройки своих «фабричных» классов. Однако методы Java, C ++ и C # не поддерживают полиморфное поведение.
Теоретически разработчики Java могли позволить вам реализовать реализации метода интерфейса с помощью методов static
в случае, если реализация не нуждается в доступе состояние из экземпляра. Но такое же поведение легко достичь с помощью тривиальной оболочки:
public class MyImplementation implements MyInterface {
public MyImplementation(String name) {
}
@Override
public MyInterface getInstance() { // static is not allowed here
return getInstanceImpl();
}
public static getInstanceImpl() {
return new MyImplementation(name)
}
}
Компилятор Java мог бы сделать то же самое от вашего имени, но, увидев, что статический метод реализует метод экземпляра, является необычным и запутанным, поэтому я предполагаю, что разработчики Java решили отказаться от предоставления этого «волшебства».
Пример ответа @ Насера:
>>> import pandas as pd
>>> import numpy as np
>>> df = pd.DataFrame(columns=['lib', 'qty1', 'qty2'])
>>> for i in range(5):
>>> df.loc[i] = [np.random.randint(-1,1) for n in range(3)]
>>>
>>> print(df)
lib qty1 qty2
0 0 0 -1
1 -1 -1 1
2 1 -1 1
3 0 0 0
4 1 -1 -1
[5 rows x 3 columns]
Вы также можете создать список списков и преобразовать их в dataframe -
import pandas as pd
rows = []
columns = ['i','double','square']
for i in range(6):
row = [i, i*2, i*i]
rows.append(row)
df = pd.DataFrame(rows, columns=columns)
, давая
i double square 0 0 0 0 1 1 2 1 2 2 4 4 3 3 6 9 4 4 8 16 5 5 10 25
Для эффективного добавления см. . Как добавить дополнительную строку в набор данных pandas и с расширением .
Добавить строки через loc/ix
в несуществующие данные индекса ключа. например :
In [1]: se = pd.Series([1,2,3])
In [2]: se
Out[2]:
0 1
1 2
2 3
dtype: int64
In [3]: se[5] = 5.
In [4]: se
Out[4]:
0 1.0
1 2.0
2 3.0
5 5.0
dtype: float64
Или:
In [1]: dfi = pd.DataFrame(np.arange(6).reshape(3,2),
.....: columns=['A','B'])
.....:
In [2]: dfi
Out[2]:
A B
0 0 1
1 2 3
2 4 5
In [3]: dfi.loc[:,'C'] = dfi.loc[:,'A']
In [4]: dfi
Out[4]:
A B C
0 0 1 0
1 2 3 2
2 4 5 4
In [5]: dfi.loc[3] = 5
In [6]: dfi
Out[6]:
A B C
0 0 1 0
1 2 3 2
2 4 5 4
3 5 5 5
Если вы знаете количество записей ex ante, вы должны предварительно распределить пространство, указав индекс (принимая пример данных из другого ответа):
import pandas as pd
import numpy as np
# we know we're gonna have 5 rows of data
numberOfRows = 5
# create dataframe
df = pd.DataFrame(index=np.arange(0, numberOfRows), columns=('lib', 'qty1', 'qty2') )
# now fill it up row by row
for x in np.arange(0, numberOfRows):
#loc or iloc both work here since the index is natural numbers
df.loc[x] = [np.random.randint(-1,1) for n in range(3)]
In[23]: df
Out[23]:
lib qty1 qty2
0 -1 -1 -1
1 0 0 0
2 -1 0 -1
3 0 -1 0
4 -1 0 0
Сравнение скорости
In[30]: %timeit tryThis() # function wrapper for this answer
In[31]: %timeit tryOther() # function wrapper without index (see, for example, @fred)
1000 loops, best of 3: 1.23 ms per loop
100 loops, best of 3: 2.31 ms per loop
И - как из комментариев - с размером 6000, разница в скорости становится еще больше:
Увеличение размера массива (12) и количества строк (500) делает разницу скорости более яркой: 313ms против 2.29s
blockquote>
Для путинского пути здесь добавьте мой ответ:
res = pd.DataFrame(columns=('lib', 'qty1', 'qty2'))
res = res.append([{'qty1':10.0}], ignore_index=True)
print(res.head())
lib qty1 qty2
0 NaN 10.0 NaN
Создайте новую запись (кадр данных) и добавьте в old_data_frame. передать список значений и соответствующие им имена столбцов для создания new_record (data_frame)
new_record = pd.DataFrame([[0,'abcd',0,1,123]],columns=['a','b','c','d','e'])
old_data_frame = pd.concat([old_data_frame,new_record])
mycolumns = ['A', 'B']
df = pd.DataFrame(columns=mycolumns)
rows = [[1,2],[3,4],[5,6]]
for row in rows:
df.loc[len(df)] = row
Вы можете использовать pandas.concat()
или DataFrame.append()
. Подробнее и примеры см. В разделе Слияние, объединение и конкатенация .
.loc
, которого можно избежать, особенно если вы осторожны.
– Ken Williams
16 March 2017 в 17:03
DataFrame.append()
, вы должны убедиться, что данные вашей строки также являются DataFrame, а не списком.
– StayFoolish
8 September 2017 в 12:46
Это было давно, но я столкнулся с такой же проблемой. И нашел здесь много интересных ответов. Поэтому я смутил, какой метод использовать.
В случае добавления большого количества строк в dataframe мне интересна скорость. Итак, я пробовал 3 самых популярных метода и проверял их скорость.
Результаты (в секундах):
Adding 1000 rows 5000 rows 10000 rows
.append 1.04 4.84 9.56
.loc 1.16 5.59 11.50
dict 0.23 0.26 0.34
Поэтому я использую дополнение через словарь для себя.
Код :
import pandas
import numpy
import time
numOfRows = 10000
startTime = time.perf_counter()
df1 = pandas.DataFrame(numpy.random.randint(100, size=(5,5)), columns=['A', 'B', 'C', 'D', 'E'])
for i in range( 1,numOfRows):
df1 = df1.append( dict( (a,numpy.random.randint(100)) for a in ['A','B','C','D','E']), ignore_index=True)
print('Elapsed time: {:6.3f} seconds for {:d} rows'.format(time.perf_counter() - startTime, numOfRows))
startTime = time.perf_counter()
df2 = pandas.DataFrame(numpy.random.randint(100, size=(5,5)), columns=['A', 'B', 'C', 'D', 'E'])
for i in range( 1,numOfRows):
df2.loc[df2.index.max()+1] = numpy.random.randint(100, size=(1,5))[0]
print('Elapsed time: {:6.3f} seconds for {:d} rows'.format(time.perf_counter() - startTime, numOfRows))
startTime = time.perf_counter()
row_list = []
for i in range (0,5):
row_list.append(dict( (a,numpy.random.randint(100)) for a in ['A','B','C','D','E']))
for i in range( 1,numOfRows):
dict1 = dict( (a,numpy.random.randint(100)) for a in ['A','B','C','D','E'])
row_list.append(dict1)
df3 = pandas.DataFrame(row_list, columns=['A','B','C','D','E'])
print('Elapsed time: {:6.3f} seconds for {:d} rows'.format(time.perf_counter() - startTime, numOfRows))
PS Я считаю, что моя реализация не идеальна, и, возможно, есть какая-то оптимизация.
Другой способ сделать это (возможно, не очень результативный):
# add a row
def add_row(df, row):
colnames = list(df.columns)
ncol = len(colnames)
assert ncol == len(row), "Length of row must be the same as width of DataFrame: %s" % row
return df.append(pd.DataFrame([row], columns=colnames))
Вы также можете улучшить класс DataFrame следующим образом:
import pandas as pd
def add_row(self, row):
self.loc[len(self.index)] = row
pd.DataFrame.add_row = add_row
Если вы можете получить все данные для фрейма данных заранее, существует гораздо более быстрый подход, чем добавление к кадру данных:
У меня была аналогичная задача, для которой добавление к кадру данных по строкам заняло 30 минут и создание кадра данных из списка словарей, завершенных в течение нескольких секунд.
rows_list = []
for row in input_rows:
dict1 = {}
# get input row in dictionary format
# key = col_name
dict1.update(blah..)
rows_list.append(dict1)
df = pd.DataFrame(rows_list)
It is worth noting however, that concat (and therefore append) makes a full copy of the data, and that constantly reusing this function can create a significant performance hit. If you need to use the operation over several datasets, use a list comprehension.
( pandas.pydata.org/pandas-docs/stable/… )
– thikonom
25 December 2015 в 23:01
Это позаботится о добавлении элемента в пустой DataFrame. Проблема в том, что df.index.max () == nan для первого индекса:
df = pd.DataFrame(columns=['timeMS', 'accelX', 'accelY', 'accelZ', 'gyroX', 'gyroY', 'gyroZ'])
df.loc[0 if math.isnan(df.index.max()) else df.index.max() + 1] = [x for x in range(7)]
Это не ответ на вопрос 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)
import pandas as pd
t1=pd.DataFrame()
for i in range(len(the number of rows)):
#add rows as columns
t1[i]=list(rows)
t1=t1.transpose()
t1.columns=list(columns)
Сделайте это простым. Принимая список в качестве ввода, который будет добавлен в строку в кадре данных: -
import pandas as pd
res = pd.DataFrame(columns=('lib', 'qty1', 'qty2'))
for i in range(5):
res_list = list(map(int, input().split()))
res = res.append(pd.Series(res_list,index=['lib','qty1','qty2']), ignore_index=True)
Вы можете добавить одну строку в качестве словаря, используя опцию ignore_index
.
>>> f = pandas.DataFrame(data = {'Animal':['cow','horse'], 'Color':['blue', 'red']})
>>> f
Animal Color
0 cow blue
1 horse red
>>> f.append({'Animal':'mouse', 'Color':'black'}, ignore_index=True)
Animal Color
0 cow blue
1 horse red
2 mouse black
f.append(<stuff>)
создает новый объект, а не просто добавляет текущий объект на место, поэтому, если вы пытаетесь добавить к фреймворку данных в скрипте, вам нужно сказать f = f.append(<stuff>)
– Blairg23
28 May 2016 в 03:57
.loc
ссылается на индексный столбец, поэтому, если вы работаете с ранее существующим DataFrame с индексом, который не является непрерывной последовательностью целых чисел, начиная с 0 (как в вашем примере),.loc
будет перезаписывать существующие строки , или вставить строки, или создать пробелы в вашем индексе. Более надежный (но не безупречный) подход для добавления существующего ненулевого фрейма данных будет:df.loc[df.index.max() + 1] = [randint(...
или предустановить индекс, как предлагается @FooBar. – hobs 25 September 2015 в 23:21